feat : In home page "get statement" worked.

feat : After 5 minutes session timeout automatically.
feat: realtime otp feature up
This commit is contained in:
2025-10-09 14:22:39 +05:30
parent 75a4e9199b
commit 8a194a5855
17 changed files with 326 additions and 139 deletions

View File

@@ -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<string | null>(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}
</Box>
{/* this model for session logout */}
<Modal
opened={sessionModal}
onClose={() => setSessionModal(false)}
withCloseButton={false}
centered
closeOnClickOutside={false} // <--- prevents clicking outside to close
closeOnEscape={false} // <--- prevents ESC key
title="Session Timeout Warning"
>
<Stack align="center" gap="md">
<Text ta="center" c="red">
You have been inactive for a while.
<br />
Youll be logged out automatically in <b>{countdown}</b> seconds.
</Text>
<Group justify="center" mt="sm">
{/* <Button color="gray" variant="default" onClick={() => setSessionModal(false)}>
Stay Logged In
</Button> */}
<Button color="red" onClick={doLogout}>
Logout Now
</Button>
</Group>
</Stack>
</Modal>
<Divider size="xs" color="blue" />