Hire+Plus! For Employees Here's how I built it (Redux - Profile)
Tags: react, webdev, programming, tutorial
Published: 2022-08-05 05:22:00

**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.

```json
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. 

```javascript
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.

```javascript
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!