logout function added
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
|
"@reduxjs/toolkit": "^2.4.0",
|
||||||
"@tanstack/react-query": "^5.62.3",
|
"@tanstack/react-query": "^5.62.3",
|
||||||
"@testing-library/jest-dom": "^5.17.0",
|
"@testing-library/jest-dom": "^5.17.0",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
@@ -15,8 +16,10 @@
|
|||||||
"react-apexcharts": "^1.7.0",
|
"react-apexcharts": "^1.7.0",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-icons": "^5.4.0",
|
"react-icons": "^5.4.0",
|
||||||
|
"react-redux": "^9.1.2",
|
||||||
"react-router-dom": "^7.0.2",
|
"react-router-dom": "^7.0.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
|
"redux": "^5.0.1",
|
||||||
"sass": "^1.82.0",
|
"sass": "^1.82.0",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import { useMutation } from '@tanstack/react-query'
|
import { useMutation } from '@tanstack/react-query'
|
||||||
|
import { useDispatch } from 'react-redux'
|
||||||
|
|
||||||
import LoginImg from '../../assets/bg/login.svg'
|
import LoginImg from '../../assets/bg/login.svg'
|
||||||
|
|
||||||
import { Link, useNavigate } from 'react-router-dom'
|
import { Link, useNavigate } from 'react-router-dom'
|
||||||
import siteLinks from '../../links/siteLinks'
|
import siteLinks from '../../links/siteLinks'
|
||||||
import { loginUser } from '../../services/services'
|
import { loginUser } from '../../services/services'
|
||||||
|
import { updateUserDetails } from '../../store/UserDetails'
|
||||||
|
|
||||||
export default function Login() {
|
export default function Login() {
|
||||||
|
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const [fields, setFields] = useState({
|
const [fields, setFields] = useState({
|
||||||
@@ -17,7 +21,6 @@ export default function Login() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const handleChange = ({target:{name, value}}) => {
|
const handleChange = ({target:{name, value}}) => {
|
||||||
console.log('working')
|
|
||||||
setFields(prev => ({...prev, [name]:value}))
|
setFields(prev => ({...prev, [name]:value}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,10 +30,15 @@ export default function Login() {
|
|||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.log('error', error)
|
console.log('error', error)
|
||||||
|
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: (res) => {
|
||||||
navigate('/dash') // later add redux to dispatch state
|
const {token} = res?.data?.data
|
||||||
|
if(token){
|
||||||
|
localStorage.setItem('token', token)
|
||||||
|
const data = {token}
|
||||||
|
dispatch(updateUserDetails({ ...data }));
|
||||||
|
navigate('/dash') // later add redux to dispatch state
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -71,6 +79,13 @@ export default function Login() {
|
|||||||
<Link to={siteLinks.forgetpwd} className="ml-auto">Forgot Password ?</Link>
|
<Link to={siteLinks.forgetpwd} className="ml-auto">Forgot Password ?</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{login.error &&
|
||||||
|
<>
|
||||||
|
<div className="col-12 mt-3">
|
||||||
|
<p className='text-danger'>Unable to login, try agian!</p>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
<div className="col-12 mt-3">
|
<div className="col-12 mt-3">
|
||||||
<button type='button' onClick={()=>{login.mutate(fields)}} className="btn btn-primary text-uppercase">{login.isPending ? 'loading...' : 'Sign In'}</button>
|
<button type='button' onClick={()=>{login.mutate(fields)}} className="btn btn-primary text-uppercase">{login.isPending ? 'loading...' : 'Sign In'}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { Outlet, useNavigate } from 'react-router-dom'
|
import { Outlet, useNavigate } from 'react-router-dom'
|
||||||
|
import { updateUserDetails } from "../../store/UserDetails";
|
||||||
import MainLoaderBS from '../loaders/MainLoaderBS'
|
import MainLoaderBS from '../loaders/MainLoaderBS'
|
||||||
import Layout from '../layout/Layout'
|
import Layout from '../layout/Layout'
|
||||||
import siteLinks from '../../links/siteLinks'
|
import siteLinks from '../../links/siteLinks'
|
||||||
@@ -12,8 +14,15 @@ export default function UserExist() {
|
|||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true)
|
const [loading, setLoading] = useState(true)
|
||||||
|
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
const [lastActivityTime, setLastActivityTime] = useState(Date.now()); // HOLDS THE INITIAL TIME USER LOGS IN
|
const [lastActivityTime, setLastActivityTime] = useState(Date.now()); // HOLDS THE INITIAL TIME USER LOGS IN
|
||||||
|
|
||||||
|
const { userDetails: { token }} = useSelector((state) => state?.userDetails); // CHECKS IF USER Details are avaliable, to determine if user is active
|
||||||
|
|
||||||
|
let loggedIn = token ? true : false; // variable to determine if user is logged in
|
||||||
|
// console.log('loggedIn', loggedIn)
|
||||||
|
|
||||||
// Function to log the user out
|
// Function to log the user out
|
||||||
const logoutUser = () => {
|
const logoutUser = () => {
|
||||||
@@ -49,34 +58,20 @@ export default function UserExist() {
|
|||||||
}
|
}
|
||||||
},[lastActivityTime])
|
},[lastActivityTime])
|
||||||
|
|
||||||
// Setting up event listeners for user activity
|
|
||||||
// useEffect(() => {
|
|
||||||
// // Listen for activity events
|
|
||||||
// const events = ['mousemove', 'keydown', 'click', 'scroll', 'touchstart'];
|
|
||||||
|
|
||||||
// // Adding event listeners
|
|
||||||
// events.forEach(event => {
|
|
||||||
// window.addEventListener(event, resetTimer);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // Start the timer initially
|
|
||||||
// // resetTimer();
|
|
||||||
|
|
||||||
// // Cleanup event listeners when the component unmounts
|
|
||||||
// return () => {
|
|
||||||
// events.forEach(event => {
|
|
||||||
// window.removeEventListener(event, resetTimer);
|
|
||||||
// });
|
|
||||||
// // if (timer) {
|
|
||||||
// // clearTimeout(timer);
|
|
||||||
// // setTimer(null);
|
|
||||||
// // }
|
|
||||||
// };
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
|
let token = localStorage.getItem('token')
|
||||||
const timer = setTimeout(()=>{
|
const timer = setTimeout(()=>{
|
||||||
|
if(token && loggedIn){
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
}else if(token && !loggedIn){
|
||||||
|
const data = {token}
|
||||||
|
dispatch(updateUserDetails({ ...data }));
|
||||||
|
setLoading(false)
|
||||||
|
// dispatch(updateUserDetails({ ...res.data }));
|
||||||
|
}else{
|
||||||
|
navigate('auth/login')
|
||||||
|
}
|
||||||
},1000)
|
},1000)
|
||||||
|
|
||||||
return () => clearTimeout(timer)
|
return () => clearTimeout(timer)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import getImage from "../../../utils/getImage";
|
import getImage from "../../../utils/getImage";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
|
|
||||||
export default function UserHeader(){
|
export default function UserHeader(){
|
||||||
@@ -18,6 +19,13 @@ export default function UserHeader(){
|
|||||||
// e.preventDefault()
|
// e.preventDefault()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
localStorage.clear()
|
||||||
|
navigate('/login', {replace: true})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="app-header top-bar">
|
<header className="app-header top-bar">
|
||||||
<nav className="navbar navbar-expand-md">
|
<nav className="navbar navbar-expand-md">
|
||||||
@@ -280,7 +288,7 @@ export default function UserHeader(){
|
|||||||
<h4 className="text-white mb-0">Alice Williams</h4>
|
<h4 className="text-white mb-0">Alice Williams</h4>
|
||||||
<small className="text-white">Henry@example.com</small>
|
<small className="text-white">Henry@example.com</small>
|
||||||
</div>
|
</div>
|
||||||
<a href="#" className="text-white font-20 tooltip-wrapper" data-toggle="tooltip"
|
<a href="#" onClick={logout} className="text-white font-20 tooltip-wrapper" data-toggle="tooltip"
|
||||||
data-placement="top" title="" data-original-title="Logout"> <i
|
data-placement="top" title="" data-original-title="Logout"> <i
|
||||||
className="zmdi zmdi-power"></i></a>
|
className="zmdi zmdi-power"></i></a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Link, useLocation } from 'react-router-dom'
|
import { Link, useLocation, useNavigate } from 'react-router-dom'
|
||||||
import siteLinks from '../../../links/siteLinks'
|
import siteLinks from '../../../links/siteLinks'
|
||||||
import { IoIosArrowDown } from 'react-icons/io'
|
import { IoIosArrowDown } from 'react-icons/io'
|
||||||
export default function UserMenu() {
|
export default function UserMenu() {
|
||||||
|
|
||||||
const {pathname} = useLocation()
|
const {pathname} = useLocation()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
localStorage.clear()
|
||||||
|
navigate('/login', {replace: true})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="sidebar-nav scrollbar scroll_dark">
|
<div className="sidebar-nav scrollbar scroll_dark">
|
||||||
@@ -48,7 +55,7 @@ export default function UserMenu() {
|
|||||||
|
|
||||||
<li className="sidebar-banner p-4 bg-gradient text-center m-3 d-block rounded">
|
<li className="sidebar-banner p-4 bg-gradient text-center m-3 d-block rounded">
|
||||||
<h5 className="text-white mb-1">MERMS Panel</h5>
|
<h5 className="text-white mb-1">MERMS Panel</h5>
|
||||||
<Link className="btn btn-square btn-inverse-light btn-xs d-inline-block mt-2 mb-0" to={siteLinks.login}> Log Out</Link>
|
<Link className="btn btn-square btn-inverse-light btn-xs d-inline-block mt-2 mb-0" to='' onClick={logout}> Log Out</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+7
-2
@@ -1,8 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
// import './index.css';
|
// import './index.css';
|
||||||
import App from './App';
|
import { Provider } from 'react-redux';
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
|
import store from './store/store'
|
||||||
|
|
||||||
|
import App from './App';
|
||||||
//import reportWebVitals from './reportWebVitals';
|
//import reportWebVitals from './reportWebVitals';
|
||||||
import 'bootstrap/dist/css/bootstrap.css';
|
import 'bootstrap/dist/css/bootstrap.css';
|
||||||
import 'bootstrap/dist/js/bootstrap.min.js'
|
import 'bootstrap/dist/js/bootstrap.min.js'
|
||||||
@@ -14,7 +17,9 @@ const root = ReactDOM.createRoot(document.getElementById('root'));
|
|||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<App />
|
<Provider store={store}>
|
||||||
|
<App />
|
||||||
|
</Provider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { createSlice } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
userDetails: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const userSlice = createSlice({
|
||||||
|
name: "userDetails",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
updateUserDetails: (state, action) => {
|
||||||
|
state.userDetails = { ...action.payload };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Action creators are generated for each case reducer function
|
||||||
|
export const { updateUserDetails } = userSlice.actions;
|
||||||
|
|
||||||
|
export default userSlice.reducer;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { configureStore } from "@reduxjs/toolkit";
|
||||||
|
|
||||||
|
import userDetailReducer from "./UserDetails";
|
||||||
|
|
||||||
|
|
||||||
|
export default configureStore({
|
||||||
|
reducer: {
|
||||||
|
userDetails: userDetailReducer,
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user