diff --git a/src/pages/Blogs/BlogReactions.tsx b/src/pages/Blogs/BlogReactions.tsx index b9c16ae1..5d95a207 100644 --- a/src/pages/Blogs/BlogReactions.tsx +++ b/src/pages/Blogs/BlogReactions.tsx @@ -35,6 +35,11 @@ const BlogReaction: React.FC = ({ blogId }) => { const typedReactions: Reaction = reactions; useEffect(() => { + const storedReaction = localStorage.getItem(`reaction_${blogId}`); + if (storedReaction) { + setCurrentReaction(storedReaction); + } + if (blogId) { dispatch(getReactionsByBlogId(blogId)); } @@ -44,13 +49,18 @@ const BlogReaction: React.FC = ({ blogId }) => { if (type === currentReaction) { await dispatch(removeReactionAction(blogId)); setCurrentReaction(null); + localStorage.removeItem(`reaction_${blogId}`); } else { if (currentReaction) { await dispatch(removeReactionAction(blogId)); + localStorage.removeItem(`reaction_${blogId}`); } + await dispatch(addReactionAction(blogId, type)); setCurrentReaction(type); + localStorage.setItem(`reaction_${blogId}`, type); } + dispatch(getReactionsByBlogId(blogId)); setShowReactionsMenu(false); }; @@ -59,9 +69,6 @@ const BlogReaction: React.FC = ({ blogId }) => { ? Object.values(typedReactions).reduce((total, count) => total + count, 0) : 0; - useEffect(() => { - }, [typedReactions, totalReactions]); - return (
); }; -export default BlogReaction; \ No newline at end of file +export default BlogReaction; diff --git a/src/redux/actions/reactionActions.tsx b/src/redux/actions/reactionActions.tsx index de331b26..d1fbf744 100644 --- a/src/redux/actions/reactionActions.tsx +++ b/src/redux/actions/reactionActions.tsx @@ -16,17 +16,27 @@ export const getReactionsByBlogId = (blogId: string) => async (dispatch: any) => const response = await axios.post("/", { query: ` query GetReactionsByBlog($blog: ID!) { - getAllReactionsCount(blog: $blog) + getReactionsByBlog(blog: $blog) { + id + type + } } `, variables: { blog: blogId }, }); - const reactionsData = response?.data?.data?.getAllReactionsCount; - dispatch(creator(fetchReactions.FETCH_REACTIONS_SUCCESS, reactionsData)); - } catch (err: any) {} + const reactions = response?.data?.data?.getReactionsByBlog; + const reactionCounts = reactions.reduce((acc: any, reaction: any) => { + acc[reaction.type] = (acc[reaction.type] || 0) + 1; + return acc; + }, {}); + + dispatch(creator(fetchReactions.FETCH_REACTIONS_SUCCESS, reactionCounts)); + } catch (err: any) { + dispatch(creator(fetchReactions.FETCH_REACTIONS_FAILURE, err.message)); + toast.error("Failed to fetch reactions."); + } }; - export const addReactionAction = (blogId: string, type: string) => async (dispatch: any) => { const userId = localStorage.getItem("userId"); @@ -64,7 +74,10 @@ export const addReactionAction = (blogId: string, type: string) => async (dispat const reaction = response?.data?.data?.addReaction; dispatch(creator(addReaction.ADD_REACTION_SUCCESS, reaction)); toast.success("Reaction added successfully!"); - } catch (err: any) {} + } catch (err: any) { + dispatch(creator(addReaction.ADD_REACTION_FAIL, err.message)); + toast.error("Failed to add reaction."); + } }; export const removeReactionAction = (blogId: string) => async (dispatch: any) => { @@ -90,5 +103,9 @@ export const removeReactionAction = (blogId: string) => async (dispatch: any) => }); dispatch(creator(removeReaction.REMOVE_REACTION_SUCCESS, { userId, blogId })); - } catch (err: any) {} -}; \ No newline at end of file + toast.success("Reaction removed successfully!"); + } catch (err: any) { + dispatch(creator(removeReaction.REMOVE_REACTION_FAIL, err.message)); + toast.error("Failed to remove reaction."); + } +}; diff --git a/src/redux/actiontypes/reactionTypes.tsx b/src/redux/actiontypes/reactionTypes.tsx index 4af5715c..178f771b 100644 --- a/src/redux/actiontypes/reactionTypes.tsx +++ b/src/redux/actiontypes/reactionTypes.tsx @@ -1,7 +1,7 @@ export enum fetchReactions { FETCH_REACTIONS_LOADING = "FETCH_REACTIONS_LOADING", FETCH_REACTIONS_SUCCESS = "FETCH_REACTIONS_SUCCESS", - FETCH_REACTIONS_FAIL = "FETCH_REACTIONS_FAIL", + FETCH_REACTIONS_FAILURE = "FETCH_REACTIONS_FAILURE", } export enum addReaction { diff --git a/src/redux/index.ts b/src/redux/index.ts index 96262f10..33ed888f 100644 --- a/src/redux/index.ts +++ b/src/redux/index.ts @@ -134,4 +134,13 @@ export const FETCH_REPLIES_SUCCESS = "FETCH_REPLIES_SUCCESS"; export const FETCH_REPLIES_FAIL = "FETCH_REPLIES_FAIL"; export const ADD_REPLY_LOADING = "ADD_REPLY_LOADING"; export const ADD_REPLY_SUCCESS = "ADD_REPLY_SUCCESS"; -export const ADD_REPLY_FAIL = "ADD_REPLY_FAIL"; \ No newline at end of file +export const ADD_REPLY_FAIL = "ADD_REPLY_FAIL"; +export const FETCH_REACTIONS_LOADING = "FETCH_REACTIONS_LOADING"; +export const FETCH_REACTIONS_SUCCESS = "FETCH_REACTIONS_SUCCESS"; +export const FETCH_REACTIONS_FAILURE = "FETCH_REACTIONS_FAILURE"; +export const ADD_REACTION_LOADING = "ADD_REACTION_LOADING"; +export const ADD_REACTION_SUCCESS = "ADD_REACTION_SUCCESS"; +export const ADD_REACTION_FAILURE = "ADD_REACTION_FAILURE"; +export const REMOVE_REACTION_LOADING = "REMOVE_REACTION_LOADING"; +export const REMOVE_REACTION_SUCCESS = "REMOVE_REACTION_SUCCESS"; +export const REMOVE_REACTION_FAILURE = "REMOVE_REACTION_FAILURE"; \ No newline at end of file diff --git a/src/redux/reducers/reactionReducers.tsx b/src/redux/reducers/reactionReducers.tsx index cf9f89ed..0f25a3ef 100644 --- a/src/redux/reducers/reactionReducers.tsx +++ b/src/redux/reducers/reactionReducers.tsx @@ -1,94 +1,97 @@ import { - fetchReactions, - addReaction, - removeReaction, - } from "../actiontypes/reactionTypes"; - - - interface ReactionState { - isReactionLoading: boolean; - reactions: Record; - errors: null | string; - } - - const initialState: ReactionState = { - isReactionLoading: false, - reactions: {}, - errors: null, - }; - - export default ( - state = initialState, - { type, payload }: { type: string; payload: any } - ): ReactionState => { - switch (type) { - case fetchReactions.FETCH_REACTIONS_LOADING: - case addReaction.ADD_REACTION_LOADING: - case removeReaction.REMOVE_REACTION_LOADING: - return { - ...state, - isReactionLoading: true, - }; - - case fetchReactions.FETCH_REACTIONS_SUCCESS: - - const transformedReactions = - typeof payload === "number" - ? { TOTAL: payload } - : Array.isArray(payload) - ? payload.reduce((acc: Record, reaction: { type: string }) => { - if (reaction.type) { - acc[reaction.type] = (acc[reaction.type] || 0) + 1; - } - return acc; - }, {}) - : {}; - + fetchReactions, + addReaction, + removeReaction, +} from "../actiontypes/reactionTypes"; + +interface ReactionState { + isReactionLoading: boolean; + reactions: Record; + errors: null | string; +} + +const initialState: ReactionState = { + isReactionLoading: false, + reactions: {}, + errors: null, +}; + +export default ( + state = initialState, + { type, payload }: { type: string; payload: any } +): ReactionState => { + switch (type) { + case fetchReactions.FETCH_REACTIONS_LOADING: + return { + ...state, + isReactionLoading: true, + errors: null, + }; + + case fetchReactions.FETCH_REACTIONS_SUCCESS: + return { + ...state, + isReactionLoading: false, + reactions: payload, + errors: null, + }; + + case fetchReactions.FETCH_REACTIONS_FAILURE: + return { + ...state, + isReactionLoading: false, + errors: payload, + }; + + case addReaction.ADD_REACTION_LOADING: + case removeReaction.REMOVE_REACTION_LOADING: + return { + ...state, + isReactionLoading: true, + errors: null, + }; + + case addReaction.ADD_REACTION_SUCCESS: { + const updatedReactions = { ...state.reactions }; + const { type } = payload; + + if (type) { + updatedReactions[type] = (updatedReactions[type] || 0) + 1; + } + return { ...state, isReactionLoading: false, - reactions: transformedReactions, + reactions: updatedReactions, + errors: null, }; - - case addReaction.ADD_REACTION_SUCCESS: - const updatedReactions = (payload || []).reduce( - (acc: Record, reaction: { type: string; count: number }) => { - acc[reaction.type] = reaction.count; - return acc; - }, - {} - ); - return { - ...state, - isReactionLoading: false, - reactions: updatedReactions, - }; - - case removeReaction.REMOVE_REACTION_SUCCESS: - const reactionsAfterRemoval = (payload || []).reduce( - (acc: Record, reaction: { type: string; count: number }) => { - acc[reaction.type] = reaction.count; - return acc; - }, - {} - ); - return { - ...state, - isReactionLoading: false, - reactions: reactionsAfterRemoval, - }; - - case fetchReactions.FETCH_REACTIONS_FAIL: - case addReaction.ADD_REACTION_FAIL: - case removeReaction.REMOVE_REACTION_FAIL: - return { - ...state, - isReactionLoading: false, - errors: payload, - }; - - default: - return state; + } + + case removeReaction.REMOVE_REACTION_SUCCESS: { + const updatedReactions = { ...state.reactions }; + const { type } = payload; + + if (type && updatedReactions[type] > 0) { + updatedReactions[type] -= 1; } - }; - \ No newline at end of file + + return { + ...state, + isReactionLoading: false, + reactions: updatedReactions, + errors: null, + }; + } + + case addReaction.ADD_REACTION_FAIL: + case removeReaction.REMOVE_REACTION_FAIL: + return { + ...state, + isReactionLoading: false, + errors: payload, + }; + + default: + return state; + } +};