From 9c3feca6a7072154a17b8b5fbdd99aaa802710e3 Mon Sep 17 00:00:00 2001 From: Kshitij Date: Fri, 18 Jul 2025 02:12:46 +0530 Subject: [PATCH] feat(login): improve error handling and show rate limit message - Display meaningful error messages on login failure, including rate limiting (429) - Added fallback for unexpected JSON responses from the server - Integrated `Message` component for error display - Cleaned up form value clearing and error state management --- Frontend/src/pages/Login/LoginPage.jsx | 92 ++++++++++++++++---------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/Frontend/src/pages/Login/LoginPage.jsx b/Frontend/src/pages/Login/LoginPage.jsx index be2a77a..df9e7e0 100644 --- a/Frontend/src/pages/Login/LoginPage.jsx +++ b/Frontend/src/pages/Login/LoginPage.jsx @@ -1,45 +1,63 @@ -import React, { useRef } from "react"; +import React, { useRef, useState } from "react"; import { useDispatch } from "react-redux"; import { Link, useNavigate, useOutletContext } from "react-router-dom"; import { userSliceActions } from "../../store/userSlice"; import { BACKEND_URL } from "../../constants"; -import { t } from "../../service/translation"; // Adjust path as needed +import { t } from "../../service/translation"; +import Message from "../../components/Message"; // Import Message component const LoginPage = () => { - // Get language from outlet context const { language } = useOutletContext(); - - console.log("LoginPage language:", language); - const emailElement = useRef(); const passwordElement = useRef(); + const [error, setError] = useState(""); // For showing errors + const navigate = useNavigate(); const dispatch = useDispatch(); const handleLogin = async (event) => { event.preventDefault(); - const responce = await fetch(`${BACKEND_URL}/api/v1/login`, { - method: "POST", - credentials: "include", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ - email: emailElement.current.value, - password: passwordElement.current.value, - }), - }); - - const user = await responce.json(); - - dispatch(userSliceActions.addUser(user.data)); - - emailElement.current.value = ""; - passwordElement.current.value = ""; - - if (user.success === true) { - navigate("/"); + setError(""); // Clear previous error + + try { + const response = await fetch(`${BACKEND_URL}/api/v1/login`, { + method: "POST", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + email: emailElement.current.value, + password: passwordElement.current.value, + }), + }); + + if (response.status === 429) { + setError("Too many login attempts. Please try again after 15 minutes."); + return; + } + + let data; + try { + data = await response.json(); + } catch (jsonError) { + setError("Unexpected server response. Please try again."); + return; + } + + if (data.success === true) { + dispatch(userSliceActions.addUser(data.data)); + navigate("/"); + } else { + setError(data.message || "Login failed. Please check your credentials."); + } + + emailElement.current.value = ""; + passwordElement.current.value = ""; + } catch (err) { + console.error("Login error:", err); + setError("Something went wrong. Please try again."); } }; @@ -55,9 +73,15 @@ const LoginPage = () => {

{t("login_title", language)}

-

- {t("login_subtitle", language)} -

+

{t("login_subtitle", language)}

+ + {/* Show error message */} + {error && ( +
+ +
+ )} +