#12 saved user state to local storage

parent 1d47c276
import React from 'react'; import React from 'react';
import {Link, useNavigate} from 'react-router-dom'; 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 Header = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const dispatch = useAppDispatch();
const {userLoggedIn} = useAppSelector((state) => state.user); const {userLoggedIn} = useAppSelector((state) => state.user);
const handleLogOut = () => {
const token: string | null = window.sessionStorage.getItem('token');
dispatch(setLogOut());
if (token) {
dispatch(logout(token));
}
};
return ( return (
<div> <div>
{!userLoggedIn ? ( {!userLoggedIn ? (
...@@ -15,12 +25,21 @@ const Header = () => { ...@@ -15,12 +25,21 @@ const Header = () => {
sign in sign in
</Link> </Link>
) : ( ) : (
<Link <div className="flex justify-between">
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" <Link
to={'track-history'} 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> 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> </div>
); );
......
...@@ -3,6 +3,7 @@ import {getArtists} from '../features/artist/artistSlice'; ...@@ -3,6 +3,7 @@ import {getArtists} from '../features/artist/artistSlice';
import {useAppDispatch, useAppSelector} from '../store/hooks'; import {useAppDispatch, useAppSelector} from '../store/hooks';
import {useNavigate} from 'react-router-dom'; import {useNavigate} from 'react-router-dom';
import Preloader from '../components/UI/Preloader'; import Preloader from '../components/UI/Preloader';
import {setUserLoggedIn} from '../features/user/userSlice';
const HomePage: React.FunctionComponent = (): React.ReactElement => { const HomePage: React.FunctionComponent = (): React.ReactElement => {
const {loading, artists} = useAppSelector((state) => state.artist); const {loading, artists} = useAppSelector((state) => state.artist);
...@@ -12,6 +13,11 @@ const HomePage: React.FunctionComponent = (): React.ReactElement => { ...@@ -12,6 +13,11 @@ const HomePage: React.FunctionComponent = (): React.ReactElement => {
useEffect(() => { useEffect(() => {
dispatch(getArtists()); dispatch(getArtists());
const loggedInUser = localStorage.getItem('user');
if (loggedInUser) {
const foundUser = JSON.parse(loggedInUser);
dispatch(setUserLoggedIn(true));
}
}, [dispatch]); }, [dispatch]);
return ( return (
......
...@@ -44,10 +44,31 @@ export const loginUser = createAsyncThunk('loginUser', async (user: IUser) => { ...@@ -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({ export const userSlice = createSlice({
name: 'user', name: 'user',
initialState, initialState,
reducers: {}, reducers: {
setUserLoggedIn: (state, action) => {
state.userLoggedIn = action.payload;
},
setLogOut: (state) => {
state.userLoggedIn = false;
localStorage.setItem('user', '');
},
},
extraReducers: (builder) => { extraReducers: (builder) => {
builder builder
.addCase(createUser.pending, (state, action) => { .addCase(createUser.pending, (state, action) => {
...@@ -69,15 +90,35 @@ export const userSlice = createSlice({ ...@@ -69,15 +90,35 @@ export const userSlice = createSlice({
}) })
.addCase( .addCase(
loginUser.fulfilled, loginUser.fulfilled,
(state, {payload}: PayloadAction<{token: string}>) => { (
state,
{
payload,
}: PayloadAction<{token: string; username: string; id: string}>
) => {
state.loading = false; state.loading = false;
state.userLoggedIn = true; state.userLoggedIn = true;
window.sessionStorage.setItem('token', payload.token); 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 userSlice.reducer;
export default interface IUser { export default interface IUser {
username: string; username: string;
password: string; password?: string;
token?: 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