Skip to content

Commit

Permalink
feat: Add US OpenClassrooms-Student-Center#4 (Profile) user profile f…
Browse files Browse the repository at this point in the history
…etching functionality + Profile component refactor + Redux state update
  • Loading branch information
reffinger committed Feb 14, 2024
1 parent 6d72d50 commit 33f1a7d
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 8 deletions.
22 changes: 19 additions & 3 deletions frontend/src/pages/Profile.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchUserProfile } from '../service/user/userApi';

const Profile = () => {
return (
const dispatch = useDispatch();
const profile = useSelector((state) => state.user);

useEffect(() => {
dispatch(fetchUserProfile());
}, [dispatch]);

console.log(profile);
return profile.user ? (
<main className='main bg-dark'>
<div className='header'>
<h1>
Welcome back
<br />
Tony Jarvis!
{profile.user.body.firstName + ' ' + profile.user.body.lastName}!
</h1>
<button className='edit-button'>Edit Name</button>
</div>
Expand Down Expand Up @@ -41,7 +53,11 @@ const Profile = () => {
</div>
</section>
</main>
) : (
<main className='main bg-dark'>
<h1>Loading...</h1>
</main>
);
};

export default Profile;
export default Profile;
11 changes: 8 additions & 3 deletions frontend/src/service/store.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import { configureStore } from '@reduxjs/toolkit';
import authSlice from '../service/user/userSlice';
import { authReducer, userReducer } from '../service/user/userSlice';

// The value of isAuthenticated is determined by
// The value of isAuthenticated is determined by
// whether there is a 'token' item in the local storage.
const preloadedState = {
auth: {
isAuthenticated: !!localStorage.getItem('token'),
},
user: {
user: null,
loading: false,
},
};

export const store = configureStore({
reducer: {
auth: authSlice,
auth: authReducer,
user: userReducer,
},
preloadedState,
});
22 changes: 22 additions & 0 deletions frontend/src/service/user/userApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,25 @@ export const authenticate = createAsyncThunk(
}
}
);

// Async thunk to fetch user profile
export const fetchUserProfile = createAsyncThunk(
'user/fetchProfile',
async () => {
const token = localStorage.getItem('token');
const response = await fetch('http://localhost:3001/api/v1/user/profile', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
},
});
const data = await response.json();
if (response.ok) {
console.log(data.message);
return data;
} else {
window.alert(data.message);
throw new Error(data.message);
}
}
);
24 changes: 22 additions & 2 deletions frontend/src/service/user/userSlice.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createSlice } from '@reduxjs/toolkit';
import { authenticate } from './userApi';
import { authenticate, fetchUserProfile } from './userApi';

// The authSlice reducer manages the state of the user's authentication status.
const authSlice = createSlice({
Expand All @@ -18,4 +18,24 @@ const authSlice = createSlice({
},
});

export default authSlice.reducer;
const userSlice = createSlice({
name: 'user',
initialState: { user: null, loading: false },
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchUserProfile.pending, (state) => {
state.loading = true;
})
.addCase(fetchUserProfile.fulfilled, (state, action) => {
state.user = action.payload;
state.loading = false;
})
.addCase(fetchUserProfile.rejected, (state) => {
state.loading = false;
});
},
});

export const authReducer = authSlice.reducer;
export const userReducer = userSlice.reducer;

0 comments on commit 33f1a7d

Please sign in to comment.