DEV Community

Cover image for Hire+Plus! For Employees Here's how I built it (Redux - Profile)
AjeaS
AjeaS

Posted on

2 1

Hire+Plus! For Employees Here's how I built it (Redux - Profile)

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[];
};
Enter fullscreen mode Exit fullscreen mode

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);
    }
);
Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

That's all for the profile/redux portion of the project, stay tuned!

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

While many AI coding tools operate as simple command-response systems, Qodo Gen 1.0 represents the next generation: autonomous, multi-step problem-solving agents that work alongside you.

Read full post

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay