#12 saved user state to local storage

parent 1d47c276
import React from 'react';
import {Link, useNavigate} from 'react-router-dom';
import {useAppSelector} from '../store/hooks';
import {useAppDispatch, useAppSelector} from '../store/hooks';
import {logout, setLogOut} from '../features/user/userSlice';
const Header = () => {
const navigate = useNavigate();
const dispatch = useAppDispatch();
const {userLoggedIn} = useAppSelector((state) => state.user);
const handleLogOut = () => {
const token: string | null = window.sessionStorage.getItem('token');
dispatch(setLogOut());
if (token) {
dispatch(logout(token));
}
};
return (
<div>
{!userLoggedIn ? (
......@@ -15,12 +25,21 @@ const Header = () => {
sign in
</Link>
) : (
<Link
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
to={'track-history'}
>
Track History
</Link>
<div className="flex justify-between">
<Link
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
to={'track-history'}
>
Track History
</Link>
<a
onClick={handleLogOut}
href="#"
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
>
Logout
</a>
</div>
)}
</div>
);
......
......@@ -3,6 +3,7 @@ import {getArtists} from '../features/artist/artistSlice';
import {useAppDispatch, useAppSelector} from '../store/hooks';
import {useNavigate} from 'react-router-dom';
import Preloader from '../components/UI/Preloader';
import {setUserLoggedIn} from '../features/user/userSlice';
const HomePage: React.FunctionComponent = (): React.ReactElement => {
const {loading, artists} = useAppSelector((state) => state.artist);
......@@ -12,6 +13,11 @@ const HomePage: React.FunctionComponent = (): React.ReactElement => {
useEffect(() => {
dispatch(getArtists());
const loggedInUser = localStorage.getItem('user');
if (loggedInUser) {
const foundUser = JSON.parse(loggedInUser);
dispatch(setUserLoggedIn(true));
}
}, [dispatch]);
return (
......
......@@ -44,10 +44,31 @@ export const loginUser = createAsyncThunk('loginUser', async (user: IUser) => {
}
});
export const logout = createAsyncThunk('logoutUser', async (token: string) => {
try {
const response = await axios.put(
`${import.meta.env.VITE_MY_URL}/users/logout`,
{},
{headers: {Authorization: token}}
);
return response.data;
} catch (err: any) {
throw new Error(err);
}
});
export const userSlice = createSlice({
name: 'user',
initialState,
reducers: {},
reducers: {
setUserLoggedIn: (state, action) => {
state.userLoggedIn = action.payload;
},
setLogOut: (state) => {
state.userLoggedIn = false;
localStorage.setItem('user', '');
},
},
extraReducers: (builder) => {
builder
.addCase(createUser.pending, (state, action) => {
......@@ -69,15 +90,35 @@ export const userSlice = createSlice({
})
.addCase(
loginUser.fulfilled,
(state, {payload}: PayloadAction<{token: string}>) => {
(
state,
{
payload,
}: PayloadAction<{token: string; username: string; id: string}>
) => {
state.loading = false;
state.userLoggedIn = true;
window.sessionStorage.setItem('token', payload.token);
const user: IUser = {
id: payload.id,
username: payload.username,
token: payload.token,
};
localStorage.setItem('user', JSON.stringify(user));
}
);
)
.addCase(logout.fulfilled, (state, action) => {
state.loading = false;
})
.addCase(logout.pending, (state, action) => {
state.loading = true;
})
.addCase(logout.rejected, (state, action) => {
state.loading = false;
});
},
});
export const {} = userSlice.actions;
export const {setUserLoggedIn, setLogOut} = userSlice.actions;
export default userSlice.reducer;
export default interface IUser {
username: string;
password: string;
password?: string;
token?: string;
id?: string;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment