From b2f504986d570b86443fa7647f8add18cb6f1d58 Mon Sep 17 00:00:00 2001 From: Sean Date: Wed, 29 Nov 2023 17:02:48 -0500 Subject: [PATCH 1/3] Added profiles state, initial profiles load on profiles page --- TODOS_GENERAL | 2 +- client/src/app/store.ts | 3 +- client/src/features/profiles/profilesSlice.ts | 61 +++++++++++++++++++ client/src/pages/Profiles/Profiles.tsx | 24 ++++++-- client/src/utilities/apis.ts | 1 + client/types/profile.ts | 21 +++++++ 6 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 client/src/features/profiles/profilesSlice.ts create mode 100644 client/src/utilities/apis.ts create mode 100644 client/types/profile.ts diff --git a/TODOS_GENERAL b/TODOS_GENERAL index c566838..9c67e07 100644 --- a/TODOS_GENERAL +++ b/TODOS_GENERAL @@ -4,4 +4,4 @@ # Add much more thorough edge case tetsing on test files. -# Testing CI testing integrations +# Create a shared types environment for front and back. diff --git a/client/src/app/store.ts b/client/src/app/store.ts index c96f450..b94adb9 100644 --- a/client/src/app/store.ts +++ b/client/src/app/store.ts @@ -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; diff --git a/client/src/features/profiles/profilesSlice.ts b/client/src/features/profiles/profilesSlice.ts new file mode 100644 index 0000000..e1fe344 --- /dev/null +++ b/client/src/features/profiles/profilesSlice.ts @@ -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; diff --git a/client/src/pages/Profiles/Profiles.tsx b/client/src/pages/Profiles/Profiles.tsx index d1dd25e..e506489 100644 --- a/client/src/pages/Profiles/Profiles.tsx +++ b/client/src/pages/Profiles/Profiles.tsx @@ -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 ( -
-

PROFILES

-
+ <> +
+

PROFILES

+
+
+ {profiles.map((profiles) => ( +
{profiles.user}
+ ))} +
+ ); }; diff --git a/client/src/utilities/apis.ts b/client/src/utilities/apis.ts new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/client/src/utilities/apis.ts @@ -0,0 +1 @@ + diff --git a/client/types/profile.ts b/client/types/profile.ts new file mode 100644 index 0000000..8a660ce --- /dev/null +++ b/client/types/profile.ts @@ -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; +} From 1c878c1969d6e7185bdb43a22fa35e674d7a6725 Mon Sep 17 00:00:00 2001 From: Sean Date: Wed, 29 Nov 2023 18:58:31 -0500 Subject: [PATCH 2/3] tests refatored and updated to reflect new Profiles component structure --- TODOS_GENERAL | 2 +- client/src/pages/MainPage/MainPage.tsx | 2 +- client/src/pages/Profiles/Profiles.test.tsx | 45 ++++++++++++++----- .../__snapshots__/Profiles.test.tsx.snap | 15 ------- 4 files changed, 36 insertions(+), 28 deletions(-) delete mode 100644 client/src/pages/Profiles/__snapshots__/Profiles.test.tsx.snap diff --git a/TODOS_GENERAL b/TODOS_GENERAL index 9c67e07..f530b14 100644 --- a/TODOS_GENERAL +++ b/TODOS_GENERAL @@ -1,4 +1,4 @@ -# 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?) diff --git a/client/src/pages/MainPage/MainPage.tsx b/client/src/pages/MainPage/MainPage.tsx index c4be41f..c5a9bb5 100644 --- a/client/src/pages/MainPage/MainPage.tsx +++ b/client/src/pages/MainPage/MainPage.tsx @@ -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 (

Main Page

diff --git a/client/src/pages/Profiles/Profiles.test.tsx b/client/src/pages/Profiles/Profiles.test.tsx index 19ca6a8..56cb89e 100644 --- a/client/src/pages/Profiles/Profiles.test.tsx +++ b/client/src/pages/Profiles/Profiles.test.tsx @@ -1,17 +1,40 @@ 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(); - const title = getByText("PROFILES"); - expect(title).toBeInTheDocument(); - }); +interface State { + profiles: { + profiles: { user: string }[]; + status: 'idle' | 'loading' | 'failed'; + error: string | null; + }; +} - it("matches the snapshot", () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); +const mockStore = configureStore([]); +const initialState: State = { + profiles: { + profiles: [ + { user: "User1" }, + { user: "User2" } + ], + status: 'idle', + error: null + } + }, +}; + +describe("MainPage Component", () => { + it("renders correctly", () => { + const store = mockStore(initialState); + const tree = create( + + + + ).toJSON(); + expect(tree).toMatchSnapshot(); }); }); + diff --git a/client/src/pages/Profiles/__snapshots__/Profiles.test.tsx.snap b/client/src/pages/Profiles/__snapshots__/Profiles.test.tsx.snap deleted file mode 100644 index 96b7ae5..0000000 --- a/client/src/pages/Profiles/__snapshots__/Profiles.test.tsx.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Profiles Page matches the snapshot 1`] = ` - -
-

- PROFILES -

-
-
-`; From 6c0a11625d64c6d9c0067f7aab04aff6bc145d2a Mon Sep 17 00:00:00 2001 From: Sean Date: Wed, 29 Nov 2023 19:02:27 -0500 Subject: [PATCH 3/3] quick fix for syntax error --- client/src/pages/Profiles/Profiles.test.tsx | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/client/src/pages/Profiles/Profiles.test.tsx b/client/src/pages/Profiles/Profiles.test.tsx index 56cb89e..b2b46d0 100644 --- a/client/src/pages/Profiles/Profiles.test.tsx +++ b/client/src/pages/Profiles/Profiles.test.tsx @@ -8,7 +8,7 @@ import Profiles from "./Profiles"; interface State { profiles: { profiles: { user: string }[]; - status: 'idle' | 'loading' | 'failed'; + status: "idle" | "loading" | "failed"; error: string | null; }; } @@ -16,13 +16,9 @@ interface State { const mockStore = configureStore([]); const initialState: State = { profiles: { - profiles: [ - { user: "User1" }, - { user: "User2" } - ], - status: 'idle', - error: null - } + profiles: [{ user: "User1" }, { user: "User2" }], + status: "idle", + error: null, }, }; @@ -37,4 +33,3 @@ describe("MainPage Component", () => { expect(tree).toMatchSnapshot(); }); }); -