From 8a194a5855fea9f624c52c575406fde8e8b14f9d Mon Sep 17 00:00:00 2001 From: "tomosa.sarkar" Date: Thu, 9 Oct 2025 14:22:39 +0530 Subject: [PATCH] feat : In home page "get statement" worked. feat : After 5 minutes session timeout automatically. feat: realtime otp feature up --- TODO.md | 15 +- .../account_statement/accountStatement.tsx | 10 +- src/app/(main)/accounts/page.tsx | 2 +- src/app/(main)/funds_transfer/page.tsx | 2 +- .../funds_transfer/send_beneficiary/page.tsx | 92 ++++++--- .../sendBeneficiaryOthers.tsx | 176 +++++++++--------- src/app/(main)/home/page.tsx | 1 + src/app/(main)/layout.tsx | 84 ++++++++- .../settings/change_login_password/page.tsx | 2 +- .../settings/change_txn_password/page.tsx | 2 +- src/app/ChangePassword/page.tsx | 2 + src/app/ForgetPassword/page.tsx | 2 +- src/app/SetPassword/page.tsx | 2 +- src/app/SetTxn/page.tsx | 2 +- src/app/_util/otp.ts | 60 ++++++ src/app/eMandate/mandate_page/page.tsx | 2 +- src/app/login/page.tsx | 9 +- 17 files changed, 326 insertions(+), 139 deletions(-) create mode 100644 src/app/_util/otp.ts diff --git a/TODO.md b/TODO.md index 785ccab..fe2953f 100644 --- a/TODO.md +++ b/TODO.md @@ -6,23 +6,28 @@ - >Taking Url and try to login -Logout ### Feature -- Password Expiry Logic - - login -> check password Expiry -> Change password -> login screen +- >Password Expiry Logic + - >login -> check password Expiry -> Change password -> login screen - >Logout popup : - >Are you sure want to logout? - >Home page password Expiry message - Set userId and login with userID -- Limit of transaction daily +- Limit of transaction daily --Asif - >Statement Download - >In Every OTP page "Resend button" & 3 min timing of expiry. - OTP binding with actual mobile number. +- Beneficiary delete feature - IN settings page NOTE position Fixing. - >Admin page - >give rights - >view rights - Forget Password -- >For Migration if user not have password + - E-mandate -- Make every page responsive + +- Locked (3 times wrong password in time of login) +- >session timeout +- login time otp + diff --git a/src/app/(main)/accounts/account_statement/accountStatement.tsx b/src/app/(main)/accounts/account_statement/accountStatement.tsx index a8d05f8..ccf1ea2 100644 --- a/src/app/(main)/accounts/account_statement/accountStatement.tsx +++ b/src/app/(main)/accounts/account_statement/accountStatement.tsx @@ -49,7 +49,7 @@ export default function AccountStatementPage() { .then(res => res.json()) .then(data => { if (Array.isArray(data)) { - const last5 = data.slice(0, 5); + const last5 = data.slice(0, 10); setTransactions(last5); // Reuse balance logic const saved = sessionStorage.getItem("accountData"); @@ -247,7 +247,7 @@ export default function AccountStatementPage() { {(!startDate && !endDate && transactions.length > 0) && ( - Last 5 Transactions + Last 10 Transactions )} @@ -290,12 +290,12 @@ export default function AccountStatementPage() { // ✅ Desktop View – Table Layout - - + {/* + - + */} {transactions.map((txn, i) => ( diff --git a/src/app/(main)/accounts/page.tsx b/src/app/(main)/accounts/page.tsx index 55ad973..7024cf5 100644 --- a/src/app/(main)/accounts/page.tsx +++ b/src/app/(main)/accounts/page.tsx @@ -32,7 +32,7 @@ export default function AccountSummary() { const data = await response.json(); if (response.ok && Array.isArray(data)) { setAccountData(data); - sessionStorage.setItem("accountData", JSON.stringify(data)); + // sessionStorage.setItem("accountData", JSON.stringify(data)); } } catch { notifications.show({ diff --git a/src/app/(main)/funds_transfer/page.tsx b/src/app/(main)/funds_transfer/page.tsx index 62a2295..27d035e 100644 --- a/src/app/(main)/funds_transfer/page.tsx +++ b/src/app/(main)/funds_transfer/page.tsx @@ -249,7 +249,7 @@ export default function QuickPay() { toAccount: beneficiaryAcc, toAccountType: beneficiaryType, amount: amount, - narration: remarks, + remarks: remarks, tpassword: txnPassword, }), }); diff --git a/src/app/(main)/funds_transfer/send_beneficiary/page.tsx b/src/app/(main)/funds_transfer/send_beneficiary/page.tsx index 033dc18..8b8135f 100644 --- a/src/app/(main)/funds_transfer/send_beneficiary/page.tsx +++ b/src/app/(main)/funds_transfer/send_beneficiary/page.tsx @@ -1,14 +1,15 @@ "use client"; -import React, { useEffect, useRef, useState } from "react"; -import { Button, Center, Group, Modal, Paper, Radio, ScrollArea, Select, Stack, Text, TextInput, Title, Box, PasswordInput } from "@mantine/core"; +import React, { useEffect, useState } from "react"; +import { Button, Group, Modal, Paper, Radio, Select, Stack, Text, TextInput, Title, PasswordInput } from "@mantine/core"; import { notifications } from "@mantine/notifications"; import { useRouter } from "next/navigation"; -import { generateOTP } from '@/app/OTPGenerator'; import SendToBeneficiaryOthers from "./sendBeneficiaryOthers"; import Image from "next/image"; import img from '@/app/image/logo1.jpg'; import { IconRefresh } from "@tabler/icons-react"; +import { sendOtp, verifyOtp } from '@/app/_util/otp'; + interface accountData { stAccountNo: string; @@ -36,25 +37,48 @@ export default function SendToBeneficiaryOwn() { const [isSubmitting, setIsSubmitting] = useState(false); const [showOtpField, setShowOtpField] = useState(false); const [otp, setOtp] = useState(""); - const [generateOtp, setGenerateOtp] = useState(""); - const [countdown, setCountdown] = useState(180); const [timerActive, setTimerActive] = useState(false); - async function handleGenerateOtp() { - // const value = await generateOTP(6); - const value = "123456"; - setGenerateOtp(value); - setCountdown(180); - setTimerActive(true); - return value; + async function handleSendOtp() { + const mobileNumber = localStorage.getItem('remitter_mobile_no'); + if (!mobileNumber) { + notifications.show({ + title: 'Error', + message: 'Mobile number not found.Contact to administrator', + color: 'red', + }); + return; + } + try { + await sendOtp({ type: 'IMPS' }); + setShowOtpField(true); + setCountdown(180); + setTimerActive(true); + } catch (err: any) { + console.error('Send OTP failed', err); + notifications.show({ + title: 'Error', + message: err.message || 'Send OTP failed.Please try again later.', + color: 'red', + }); + } } + + async function handleVerifyOtp() { + try { + await verifyOtp(otp); + return true; + } catch { + return false; + } + } + const selectedAccount = accountData.find((acc) => acc.stAccountNo === selectedAccNo); const accountOptions = accountData.map((acc) => ({ value: acc.stAccountNo, label: `${acc.stAccountNo} (${acc.stAccountType})`, })); - const FetchBeneficiaryDetails = async () => { try { const token = localStorage.getItem("access_token"); @@ -66,7 +90,7 @@ export default function SendToBeneficiaryOwn() { }, }); const data = await response.json(); - console.log(data); + // console.log(data); if (response.ok && Array.isArray(data)) { setBeneficiaryData(data); } else { @@ -195,21 +219,27 @@ export default function SendToBeneficiaryOwn() { setIsVisibilityLocked(true); return; } + if (showOtpField && !showTxnPassword) { + if (!otp) { + notifications.show({ + title: "Error", + message: "Please enter the OTP", + color: "red", + }); + return; + } - if (!otp) { - notifications.show({ - title: "Enter OTP", - message: "Please enter the OTP", - color: "red", - }); - return; - } - if (otp !== generateOtp) { - notifications.show({ - title: "Invalid OTP", - message: "The OTP entered does not match", - color: "red", - }); + const verified = await handleVerifyOtp(); + if (!verified) { + notifications.show({ + title: "Invalid OTP", + message: "The OTP entered does not match", + color: "red", + }); + return; + } + // If OTP verified successfully → show transaction password field + setShowTxnPassword(true); return; } @@ -241,7 +271,7 @@ export default function SendToBeneficiaryOwn() { toAccount: beneficiaryAcc, toAccountType: beneficiaryType, amount: amount, - narration: remarks, + remarks: remarks, tpassword: txnPassword, }), }); @@ -325,7 +355,7 @@ export default function SendToBeneficiaryOwn() { color="blue" onClick={async () => { setConfirmModel(false); - const otp = await handleGenerateOtp(); + const otp = await handleSendOtp(); setShowOtpField(true); notifications.show({ title: "OTP Sent", @@ -459,7 +489,7 @@ export default function SendToBeneficiaryOwn() { ) )} diff --git a/src/app/(main)/funds_transfer/send_beneficiary/sendBeneficiaryOthers.tsx b/src/app/(main)/funds_transfer/send_beneficiary/sendBeneficiaryOthers.tsx index 26ae83b..0787f06 100644 --- a/src/app/(main)/funds_transfer/send_beneficiary/sendBeneficiaryOthers.tsx +++ b/src/app/(main)/funds_transfer/send_beneficiary/sendBeneficiaryOthers.tsx @@ -4,10 +4,10 @@ import React, { useEffect, useRef, useState } from "react"; import { Button, Center, Divider, Group, List, Modal, Paper, PasswordInput, Radio, ScrollArea, Select, Stack, Text, TextInput, ThemeIcon, Title } from "@mantine/core"; import { notifications } from "@mantine/notifications"; import { useRouter } from "next/navigation"; -import { generateOTP } from '@/app/OTPGenerator'; import { IconAlertTriangle, IconRefresh } from "@tabler/icons-react"; import Image from "next/image"; import img from '@/app/image/logo1.jpg' +import { sendOtp, verifyOtp } from "@/app/_util/otp"; interface accountData { @@ -38,16 +38,57 @@ export default function SendToBeneficiaryOthers() { const [otp, setOtp] = useState(""); const [countdown, setCountdown] = useState(180); const [timerActive, setTimerActive] = useState(false); - const [generateOtp, setGenerateOtp] = useState(""); - async function handleGenerateOtp() { - // const value = await generateOTP(6); - const value = "123456"; - setGenerateOtp(value); - setCountdown(180); - setTimerActive(true); - return value; + async function handleSendOtp() { + const mobileNumber = localStorage.getItem('remitter_mobile_no'); + if (!mobileNumber) { + notifications.show({ + title: 'Error', + message: 'Mobile number not found.Contact to administrator', + color: 'red', + }); + return; + } + try { + if (paymentMode === "IMPS") { await sendOtp({ type: 'IMPS' }); } + if (paymentMode === "RTGS") { + await sendOtp( + { + type: 'RTGS', + amount: amount ? Number(amount) : undefined, + beneficiary: beneficiaryName || undefined + }); + } + if (paymentMode === "NEFT") { + await sendOtp( + { + type: 'NEFT', + amount: amount ? Number(amount) : undefined, + beneficiary: beneficiaryName || undefined + }); + } + setShowOtpField(true); + setCountdown(180); + setTimerActive(true); + } catch (err: any) { + console.error('Send OTP failed', err); + notifications.show({ + title: 'Error', + message: err.message || 'Send OTP failed.Please try again later.', + color: 'red', + }); + } } + + async function handleVerifyOtp() { + try { + await verifyOtp(otp); + return true; + } catch { + return false; + } + } + const getAmountError = () => { if (!amount || !selectedAccount) return null; const amt = Number(amount); @@ -78,7 +119,7 @@ export default function SendToBeneficiaryOthers() { }, }); const data = await response.json(); - console.log(data); + // console.log(data); if (response.ok && Array.isArray(data)) { setBeneficiaryData(data); } else { @@ -216,20 +257,43 @@ export default function SendToBeneficiaryOthers() { return; } - if (!otp) { - notifications.show({ - title: "Enter OTP", - message: "Please enter the OTP", - color: "red", - }); - return; - } - if (otp !== generateOtp) { - notifications.show({ - title: "Invalid OTP", - message: "The OTP entered does not match", - color: "red", - }); + // if (!otp) { + // notifications.show({ + // title: "Enter OTP", + // message: "Please enter the OTP", + // color: "red", + // }); + // return; + // } + // if (otp !== generateOtp) { + // notifications.show({ + // title: "Invalid OTP", + // message: "The OTP entered does not match", + // color: "red", + // }); + // return; + // } + if (showOtpField && !showTxnPassword) { + if (!otp) { + notifications.show({ + title: "Error", + message: "Please enter the OTP", + color: "red", + }); + return; + } + + const verified = await handleVerifyOtp(); + if (!verified) { + notifications.show({ + title: "Invalid OTP", + message: "The OTP entered does not match", + color: "red", + }); + return; + } + // If OTP verified successfully → show transaction password field + setShowTxnPassword(true); return; } @@ -271,7 +335,8 @@ export default function SendToBeneficiaryOthers() { amount: amount, beneficiaryName: beneficiaryName, remitterName: remitter_name, - tpassword: txnPassword + tpassword: txnPassword, + remarks: remarks }), }); const result = await res.json(); @@ -321,59 +386,6 @@ export default function SendToBeneficiaryOthers() { return ( <> - {/* setShowIntroModal(false)} - centered - withCloseButton={false} // force them to press OK - > - - Important Note - IMPS is available 24X7. Limit: up to ₹5,00,000. Money is transfer instantly. - NEFT is available 24x7. Can be used for any amount but not instant. - RTGS is for ₹2,00,000 and above. Available during banking hours.As per directions of RBI, RTGS transactions are subjected to the following{" "} - Time Varying Tariff in addition to the existing RTGS - Commission. The tariff will be calculated based on the time of completion - of transaction. - - - - } - > - - From 09:00 hrs to 12:00 hrs →{" "} - ₹0.00 - - - After 12:00 hrs up to 15:30 hrs →{" "} - ₹1.00 - - - After 15:30 hrs₹5.00 - - - - - • Minimum Transfer Amount on this Day is Rs. 1.00 - - - • Maximum Transfer Limit per Day is Rs. 500000.00 - - - • Available Transfer Amount on this Day is Rs. 500000.00 - - - - - - */} - setShowIntroModal(false)} @@ -456,9 +468,6 @@ export default function SendToBeneficiaryOthers() { - - - setConfirmModel(false)} @@ -491,7 +500,7 @@ export default function SendToBeneficiaryOthers() { color="blue" onClick={async () => { setConfirmModel(false); - const otp = await handleGenerateOtp(); + const otp = await handleSendOtp(); setShowOtpField(true); notifications.show({ title: "OTP Sent", @@ -505,6 +514,7 @@ export default function SendToBeneficiaryOthers() { + {/* main content */} {!showIntroModal && (
@@ -625,7 +635,7 @@ export default function SendToBeneficiaryOthers() { ) )} diff --git a/src/app/(main)/home/page.tsx b/src/app/(main)/home/page.tsx index 4f58504..0ea1c1b 100644 --- a/src/app/(main)/home/page.tsx +++ b/src/app/(main)/home/page.tsx @@ -71,6 +71,7 @@ export default function Home() { const data = await response.json(); if (response.ok && Array.isArray(data)) { SetAccountData(data); + sessionStorage.setItem("accountData", JSON.stringify(data)); if (data.length > 0) { const firstDeposit = data.find(acc => acc.stAccountType !== "LN"); const firstLoan = data.find(acc => acc.stAccountType === "LN"); diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx index 83f3e14..5c5e6c3 100644 --- a/src/app/(main)/layout.tsx +++ b/src/app/(main)/layout.tsx @@ -1,6 +1,6 @@ "use client"; import React, { useEffect, useState } from 'react'; -import { Box, Button, Divider, Group, Image, Popover, Stack, Text, Title } from '@mantine/core'; +import { Box, Button, Divider, Group, Image, Modal, Popover, Stack, Text, Title } from '@mantine/core'; import { IconBook, IconCurrencyRupee, IconHome, IconLogout, IconPhoneFilled, IconSettings } from '@tabler/icons-react'; import Link from 'next/link'; import { useRouter, usePathname } from "next/navigation"; @@ -17,6 +17,8 @@ export default function RootLayout({ children }: { children: React.ReactNode }) const [userLastLoginDetails, setUserLastLoginDetails] = useState(null); const [custname, setCustname] = useState(null); const isMobile = useMediaQuery("(max-width: 768px)"); + const [sessionModal, setSessionModal] = useState(false); + const [countdown, setCountdown] = useState(30); // 30 sec countdown before auto logout const [opened, { open, close }] = useDisclosure(false); @@ -80,6 +82,8 @@ export default function RootLayout({ children }: { children: React.ReactNode }) }); } } + + // When reload and click on back then logout useEffect(() => { // Push fake history state to trap navigation window.history.pushState(null, "", window.location.href); @@ -155,6 +159,58 @@ export default function RootLayout({ children }: { children: React.ReactNode }) fetchLoginTime(); }, []); + // LOGOUT AFTER 5 MINUTES OF INACTIVITY OR TAB SWITCH + useEffect(() => { + const INACTIVITY_LIMIT = 5 * 60 * 1000; // 5 minutes + let inactiveSince: number | null = null; + let countdownTimer: NodeJS.Timeout; + + const startCountdown = () => { + setSessionModal(true); + setCountdown(30); // start from 30 seconds + + countdownTimer = setInterval(() => { + setCountdown((prev) => { + if (prev <= 1) { + clearInterval(countdownTimer); + doLogout(); // auto logout after countdown + return 0; + } + return prev - 1; + }); + }, 1000); + }; + + const handleVisibilityChange = () => { + if (document.hidden) { + // User switched tab → mark inactive time + inactiveSince = Date.now(); + } else { + // User returned to tab + if (inactiveSince && Date.now() - inactiveSince >= INACTIVITY_LIMIT) { + // Inactive for ≥ 5 min → show modal + startCountdown(); + } + inactiveSince = null; // reset inactiveSince + } + }; + + const handleUserActivity = () => { + // Reset inactivity timestamp if user interacts + inactiveSince = null; + }; + + const activityEvents = ["mousemove", "keydown", "click", "scroll", "touchstart"]; + activityEvents.forEach((event) => window.addEventListener(event, handleUserActivity)); + document.addEventListener("visibilitychange", handleVisibilityChange); + + return () => { + activityEvents.forEach((event) => window.removeEventListener(event, handleUserActivity)); + document.removeEventListener("visibilitychange", handleVisibilityChange); + clearInterval(countdownTimer); + }; + }, []); + const navItems = [ { href: "/home", label: "Home", icon: IconHome }, { href: "/accounts", label: "Accounts", icon: IconBook }, @@ -274,6 +330,32 @@ export default function RootLayout({ children }: { children: React.ReactNode }) > {children} + {/* this model for session logout */} + setSessionModal(false)} + withCloseButton={false} + centered + closeOnClickOutside={false} // <--- prevents clicking outside to close + closeOnEscape={false} // <--- prevents ESC key + title="Session Timeout Warning" + > + + + You have been inactive for a while. +
+ You’ll be logged out automatically in {countdown} seconds. +
+ + {/* */} + + +
+
diff --git a/src/app/(main)/settings/change_login_password/page.tsx b/src/app/(main)/settings/change_login_password/page.tsx index 7d85988..a3c460d 100644 --- a/src/app/(main)/settings/change_login_password/page.tsx +++ b/src/app/(main)/settings/change_login_password/page.tsx @@ -160,7 +160,7 @@ export default function ChangePassword() { return; } const result = await response.json(); - console.log(result); + // console.log(result); if (!response.ok) { notifications.show({ title: "Failed", diff --git a/src/app/(main)/settings/change_txn_password/page.tsx b/src/app/(main)/settings/change_txn_password/page.tsx index 8d794bf..aff3c0d 100644 --- a/src/app/(main)/settings/change_txn_password/page.tsx +++ b/src/app/(main)/settings/change_txn_password/page.tsx @@ -160,7 +160,7 @@ export default function ChangePassword() { return; } const result = await response.json(); - console.log(result); + // console.log(result); if (!response.ok) { notifications.show({ title: "Failed", diff --git a/src/app/ChangePassword/page.tsx b/src/app/ChangePassword/page.tsx index 84f6b94..7b1f2f5 100644 --- a/src/app/ChangePassword/page.tsx +++ b/src/app/ChangePassword/page.tsx @@ -184,6 +184,7 @@ export default function ChangePassword() { color: "red", autoClose: false, }); + resetForm(); } else { notifications.show({ title: "Success", @@ -199,6 +200,7 @@ export default function ChangePassword() { message: err.message || "Server error, please try again later", color: "red", }); + resetForm(); } } }; diff --git a/src/app/ForgetPassword/page.tsx b/src/app/ForgetPassword/page.tsx index 9e58864..a77dbab 100644 --- a/src/app/ForgetPassword/page.tsx +++ b/src/app/ForgetPassword/page.tsx @@ -98,7 +98,7 @@ export default function ForgetLoginPwd() { }); const data = await response.json(); if (response.ok) { - console.log(data); + // console.log(data); notifications.show({ withBorder: true, color: "green", diff --git a/src/app/SetPassword/page.tsx b/src/app/SetPassword/page.tsx index 07da2ff..b004612 100644 --- a/src/app/SetPassword/page.tsx +++ b/src/app/SetPassword/page.tsx @@ -136,7 +136,7 @@ export default function SetLoginPwd() { }); const data = await response.json(); if (response.ok) { - console.log(data); + // console.log(data); notifications.show({ withBorder: true, color: "green", diff --git a/src/app/SetTxn/page.tsx b/src/app/SetTxn/page.tsx index 6d71c89..6a741fb 100644 --- a/src/app/SetTxn/page.tsx +++ b/src/app/SetTxn/page.tsx @@ -160,7 +160,7 @@ export default function SetTransactionPwd() { }); const data = await response.json(); if (response.ok) { - console.log(data); + // console.log(data); notifications.show({ withBorder: true, color: "green", diff --git a/src/app/_util/otp.ts b/src/app/_util/otp.ts new file mode 100644 index 0000000..414438b --- /dev/null +++ b/src/app/_util/otp.ts @@ -0,0 +1,60 @@ +import { notifications } from '@mantine/notifications'; +import axios from 'axios'; + +interface SendOtpPayload { + mobileNumber?: string; + type: string; + amount?: number; + beneficiary?: string; + ifsc?: string; + acctFrom?: string; + acctTo?: string; + ref?: string; + date?: string; + userOtp?: string; +} + +function getStoredMobileNumber(): string | null { + // const mobileNumber = localStorage.getItem('remitter_mobile_no'); + const mobileNumber= "7890544527"; + if (!mobileNumber) { + notifications.show({ + title: 'Missing Mobile Number', + message: 'Mobile number not found. Please re-login or update your profile.', + color: 'red', + }); + return null; + } + return mobileNumber; +} + +export async function sendOtp(payload: SendOtpPayload) { + try { + const mobileNumber = payload.mobileNumber || getStoredMobileNumber(); + const response = await axios.post( + 'http://localhost:8080/api/otp/send', + { ...payload, mobileNumber }, + { headers: { 'Content-Type': 'application/json' } } + ); + return response.data; + } catch (error: any) { + console.error('Error sending OTP:', error.response?.data || error.message); + throw error.response?.data || error; + } +} + + +export async function verifyOtp(otp: string) { + try { + const mobileNumber = getStoredMobileNumber(); + const response = await axios.post( + `http://localhost:8080/api/otp/verify?mobileNumber=${mobileNumber}`, + { otp }, + { headers: { 'Content-Type': 'application/json' } } + ); + return response.data; + } catch (error: any) { + console.error('Error verifying OTP:', error.response?.data || error.message); + throw error.response?.data || error; + } +} diff --git a/src/app/eMandate/mandate_page/page.tsx b/src/app/eMandate/mandate_page/page.tsx index c2a5ee9..ec30b2c 100644 --- a/src/app/eMandate/mandate_page/page.tsx +++ b/src/app/eMandate/mandate_page/page.tsx @@ -188,7 +188,7 @@ export default function MandatePage() { }), }); const data = await response.json(); - console.log(data) + // console.log(data) if (!response.ok) throw new Error("Failed to send OTP"); notifications.show({ diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 5481617..a14c64d 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -118,7 +118,7 @@ export default function Login() { }), }); const data = await response.json(); - console.log(data); + // console.log(data); if (data.error === "MIGRATED_USER_HAS_NO_PASSWORD") { //console.log("Migration issue detected → opening modal"); setOpened(true); @@ -141,10 +141,11 @@ export default function Login() { } setIsLogging(true); if (response.ok) { - console.log(data); + // console.log(data); const token = data.token; localStorage.setItem("access_token", token); localStorage.setItem("pswExpiryDate", data.loginPswExpiry); + // console.log("Expiry Date:",(dayjs(data.loginPswExpiry)).diff(dayjs(), "day")); // Password Expiry Logic todo if (data.loginPswExpiry && (dayjs(data.loginPswExpiry)).diff(dayjs(), "day") < 0) { @@ -155,14 +156,10 @@ export default function Login() { message: "Your password has expired, please set a new one.", autoClose: 4000, }); - - - router.push("/ChangePassword"); return; } - if (data.FirstTimeLogin === true) { router.push("/SetPassword") }
Name
Narration Date Amount (₹) Balance (₹)