import { useEffect, useState, useCallback } from 'react';
const useInactivity = (timeout, onTimeout) => {
const [isInactive, setIsInactive] = useState(false);
const resetTimer = useCallback(() => {
setIsInactive(false);
clearTimeout(window.inactivityTimer);
window.inactivityTimer = setTimeout(() => {
setIsInactive(true);
onTimeout();
}, timeout);
}, [onTimeout, timeout]);
useEffect(() => {
const events = ['mousemove', 'mousedown', 'keypress', 'scroll', 'touchstart'];
const handleActivity = () => resetTimer();
events.forEach((event) => window.addEventListener(event, handleActivity));
resetTimer();
return () => {
events.forEach((event) => window.removeEventListener(event, handleActivity));
clearTimeout(window.inactivityTimer);
};
}, [resetTimer]);
return isInactive;
};
export default useInactivity;
import React from 'react';
const Modal = ({ show, onClose }) => {
if (!show) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center z-50">
<div className="bg-white rounded-lg shadow-lg p-6 text-center max-w-md w-full">
<h2 className="text-xl font-bold mb-4">Session Timeout Warning</h2>
<p className="text-gray-600 mb-6">
You have been inactive for a while. Do you want to stay logged in?
</p>
<button
className="bg-blue-500 hover:bg-blue-600 text-white font-medium py-2 px-4 rounded"
onClick={onClose}
>
Stay Logged In
</button>
</div>
</div>
);
};
export default Modal;
import React, { useState } from 'react';
import Modal from './Modal';
import useInactivity from './useInactivity';
const MyApp = () => {
const [showModal, setShowModal] = useState(false);
useInactivity(30 * 60 * 1000, () => {
setShowModal(true);
});
const handleClose = () => {
setShowModal(false);
};
return (
<div className="p-6">
<h1 className="text-2xl font-bold mb-4">Welcome to My Next.js App</h1>
<p className="text-gray-600">Interact with the app to avoid being marked as inactive.</p>
<Modal show={showModal} onClose={handleClose} />
</div>
);
};
export default MyApp;