Skip to content

Commit

Permalink
Merge pull request #28 from Code-Hammers/profile-page
Browse files Browse the repository at this point in the history
Added profiles state, initial profiles load on profiles page
  • Loading branch information
brok3turtl3 authored Nov 30, 2023
2 parents 234dccb + 6c0a116 commit 975427e
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 34 deletions.
4 changes: 2 additions & 2 deletions TODOS_GENERAL
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Review and refactor error handling.
# Review and refactor error handling. Needs to be more consistent. Need a guidelines section.

# Review types (Do we need separate types? Will this cause issues later on?)

# Add much more thorough edge case tetsing on test files.

# Testing CI testing integrations
# Create a shared types environment for front and back.
3 changes: 2 additions & 1 deletion client/src/app/store.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { configureStore } from "@reduxjs/toolkit";
import userReducer from "../features/user/userSlice";
import profilesReducer from "../features/profiles/profilesSlice";

export const store = configureStore({
reducer: { user: userReducer },
reducer: { user: userReducer, profiles: profilesReducer },
});

export type AppDispatch = typeof store.dispatch;
Expand Down
61 changes: 61 additions & 0 deletions client/src/features/profiles/profilesSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
import { IProfile } from "../../../types/profile";

interface ProfilesState {
profiles: IProfile[]; //TODO ADD PROPER TYPING ONCE OBJECT IS FINALIZED
status: "idle" | "loading" | "failed";
error: string | null;
}

const initialState: ProfilesState = {
profiles: [],
status: "idle",
error: null,
};

export const fetchProfiles = createAsyncThunk(
"profiles/fetchProfiles",
async (_, thunkAPI) => {
try {
const response = await axios.get("/api/profiles");
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
return thunkAPI.rejectWithValue(
error.response?.data || "Error fetching profiles"
);
}
return thunkAPI.rejectWithValue("An unexpected error occurred");
}
}
);

const profilesSlice = createSlice({
name: "profiles",
initialState,
reducers: {
resetProfilesState(state) {
state.profiles = [];
state.status = "idle";
state.error = null;
},
},
extraReducers: (builder) => {
builder
.addCase(fetchProfiles.pending, (state) => {
state.status = "loading";
})
.addCase(fetchProfiles.fulfilled, (state, action) => {
state.profiles = action.payload;
state.status = "idle";
})
.addCase(fetchProfiles.rejected, (state, action) => {
state.status = "failed";
//state.error = action.payload as string; WHAT WOULD PAYLOAD LOOK LIKE HERE?
//TODO BUILD AN ERROR STATE TRACKER FOR CURRENT ERROR INFO
});
},
});

export default profilesSlice.reducer;
2 changes: 1 addition & 1 deletion client/src/pages/MainPage/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useAppSelector } from "../../app/hooks";

const MainPage = (): JSX.Element => {
const user = useAppSelector((state) => state.user.userData);
console.log("user data", user?.name);

return (
<div className="min-h-screen bg-gray-100 flex flex-col items-center justify-center">
<h1 className="text-4xl font-extrabold mb-4">Main Page</h1>
Expand Down
40 changes: 29 additions & 11 deletions client/src/pages/Profiles/Profiles.test.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import React from "react";
import { render } from "@testing-library/react";
import "@testing-library/jest-dom";
import { create } from "react-test-renderer";
import { Provider } from "react-redux";
import configureStore from "redux-mock-store";

import Profiles from "./Profiles";

describe("Profiles Page", () => {
it("renders the test H1 correctly", () => {
const { getByText } = render(<Profiles />);
const title = getByText("PROFILES");
expect(title).toBeInTheDocument();
});
interface State {
profiles: {
profiles: { user: string }[];
status: "idle" | "loading" | "failed";
error: string | null;
};
}

const mockStore = configureStore<State>([]);
const initialState: State = {
profiles: {
profiles: [{ user: "User1" }, { user: "User2" }],
status: "idle",
error: null,
},
};

it("matches the snapshot", () => {
const { asFragment } = render(<Profiles />);
expect(asFragment()).toMatchSnapshot();
describe("MainPage Component", () => {
it("renders correctly", () => {
const store = mockStore(initialState);
const tree = create(
<Provider store={store}>
<Profiles />
</Provider>
).toJSON();
expect(tree).toMatchSnapshot();
});
});
24 changes: 20 additions & 4 deletions client/src/pages/Profiles/Profiles.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
import React from "react";
import React, { useEffect } from "react";
import { useAppDispatch, useAppSelector } from "../../app/hooks";
import { fetchProfiles } from "../../features/profiles/profilesSlice";

const Profiles = (): JSX.Element => {
const dispatch = useAppDispatch();
const profiles = useAppSelector((state) => state.profiles.profiles);

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

return (
<div className="min-h-screen bg-gray-100 flex flex-col items-center justify-center">
<h1 className="text-4xl font-extrabold mb-4">PROFILES</h1>
</div>
<>
<div className="min-h-screen bg-gray-100 flex flex-col items-center justify-center">
<h1 className="text-4xl font-extrabold mb-4">PROFILES</h1>
</div>
<div>
{profiles.map((profiles) => (
<div key={profiles.user}>{profiles.user}</div>
))}
</div>
</>
);
};

Expand Down
15 changes: 0 additions & 15 deletions client/src/pages/Profiles/__snapshots__/Profiles.test.tsx.snap

This file was deleted.

1 change: 1 addition & 0 deletions client/src/utilities/apis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

21 changes: 21 additions & 0 deletions client/types/profile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
interface ISocial {
linkedIn?: string;
github?: string;
twitter?: string;
facebook?: string;
instagram?: string;
}

interface IJob {
title?: string;
company?: string;
description?: string;
date?: Date;
}

export interface IProfile {
user: string;
bio?: string;
job?: IJob;
socials?: ISocial;
}

0 comments on commit 975427e

Please sign in to comment.