Purpose: The candidate will be able to view and edit their profile.
Types, Actions, and Reducers: Profile State
Types
inside app > features > profile > profileTypes.ts
Data types for a profile. UpdatedFields
are the only fields I needed to update the profile page.
export type ProfileData = {
id: string;
email: string;
createdAt: number;
headline: string;
isForHire: boolean;
websiteURL: string;
skills: string[];
summary: string;
projects: ProjectData[];
experience: ExperienceData[];
};
export type ExperienceData = {
date: string;
position: string;
positionSummary: string;
};
export type ProjectData = {
date: string;
title: string;
summary: string;
github: string;
projectUrl: string;
};
export type UpdatedFields = {
id: string;
headline: string;
summary: string;
isForHire: boolean;
websiteURL: string;
skills: string[];
experience: ExperienceData[];
projects: ProjectData[];
};
Actions
inside app > features > profile > profileSlice.ts
The initial state for profile reducer. getProfileById
gets its profile by id
and returns the stringified version. updateProfileById
updates your profile.
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { getProfile, updateUserProfileById } from '../../../utils/firebase/firebase.utils';
import { signoutUser } from '../auth/authSlice';
import { ProfileData, UpdatedFields } from './profileTypes';
interface userState {
profile: ProfileData;
isLoading: boolean;
isEditting: boolean;
}
const initialState: userState = {
profile: {
id: '',
email: '',
createdAt: Date.now(),
headline: '',
isForHire: false,
websiteURL: '',
skills: [],
summary: '',
projects: [],
experience: [],
},
isLoading: false,
isEditting: false,
};
export const getProfileById = createAsyncThunk(
'profile/getProfileById',
async (id: string) => {
const profile = await getProfile(id);
const [profileObj] = profile;
return JSON.stringify(profileObj);
}
);
export const updateProfileById = createAsyncThunk(
'profile/updateProfileById',
async (data: UpdatedFields): Promise<void> => {
await updateUserProfileById(data);
}
);
Reducers
setEditView
- if editing is set to true, it'll show an editing page for the candidate to edit their profile.
setProjects
- will set projects from the editing page
setExperiences
- will set experiences from the editing page
extraReducers:
I handled the response states and set the state accordingly.
const profileSlice = createSlice({
name: 'profile',
initialState,
reducers: {
setEditView(state, action) {
state.isEditting = action.payload;
},
setProjects(state, action) {
state.profile.projects = action.payload;
},
setExperiences(state, action) {
state.profile.experience = action.payload;
},
},
extraReducers: (builder) => {
builder
.addCase(getProfileById.pending, (state) => {
state.isLoading = true;
})
.addCase(signoutUser.fulfilled, (state) => {
state.profile = {
id: '',
email: '',
createdAt: Date.now(),
headline: '',
isForHire: false,
websiteURL: '',
skills: [],
summary: '',
projects: [],
experience: [],
};
})
.addCase(getProfileById.fulfilled, (state, action) => {
state.isLoading = false;
state.profile = JSON.parse(action.payload);
})
.addCase(getProfileById.rejected, (state, action) => {
state.isLoading = false;
console.log('error with profile', action.error);
});
},
});
export const { setEditView, setProjects, setExperiences } =
profileSlice.actions;
export default profileSlice.reducer;
That's all for the profile/redux portion of the project, stay tuned!
Top comments (0)