All files / store/reducers/posts posts-reducer.ts

0% Statements 0/38
0% Branches 0/27
0% Functions 0/14
0% Lines 0/29

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128                                                                                                                                                                                                                                                               
import { PostsState } from '@/types/hackernews';
import { Action } from '@/helpers/actionHelper';
import {
  fetchNewPosts,
  fetchNewPostsSuccess,
  fetchNewPostsFailure,
  fetchTopPosts,
  fetchTopPostsSuccess,
  fetchTopPostsFailure,
  loadNewPostItem,
  loadTopPostItem,
  updateNewPostItem,
  updateTopPostItem,
  resetPosts,
} from './posts-actions';
 
const initialState: PostsState = {
  newPostItems: [],
  topPostItems: [],
  loading: false,
  error: null,
  currentPage: 1,
  totalPages: 0,
};
 
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type PostsAction = Action<any>;
 
const _fetchPosts = (state: PostsState, action: PostsAction): PostsState => ({
  ...state,
  loading: true,
  error: null,
  currentPage: action.payload?.page || 1,
});
 
const _fetchNewPostsSuccess = (state: PostsState, action: PostsAction): PostsState => {
  if (!action.payload) return state;
  return {
    ...state,
    loading: false,
    newPostItems: action.payload.items,
    currentPage: action.payload.page,
    totalPages: action.payload.totalPages,
  };
};
 
const _fetchTopPostsSuccess = (state: PostsState, action: PostsAction): PostsState => {
  if (!action.payload) return state;
  return {
    ...state,
    loading: false,
    topPostItems: action.payload.items,
    currentPage: action.payload.page,
    totalPages: action.payload.totalPages,
  };
};
 
const _fetchPostsFailure = (state: PostsState, action: PostsAction): PostsState => ({
  ...state,
  loading: false,
  error: action.payload || 'Unknown error',
});
 
const _loadNewPostItem = (state: PostsState, action: PostsAction): PostsState => {
  if (!action.payload) return state;
  return {
    ...state,
    newPostItems: state.newPostItems.map((item, idx) =>
      idx === action.payload.index ? { ...item, ...action.payload.item } : item
    ),
  };
};
 
const _updateNewPostItem = (state: PostsState, action: PostsAction): PostsState => {
  if (!action.payload) return state;
  return {
    ...state,
    newPostItems: state.newPostItems.map((item, idx) =>
      idx === action.payload.index ? { ...item, ...action.payload.item } : item
    ),
  };
};
 
const _loadTopPostItem = (state: PostsState, action: PostsAction): PostsState => {
  if (!action.payload) return state;
  return {
    ...state,
    topPostItems: state.topPostItems.map((item, idx) =>
      idx === action.payload.index ? { ...item, ...action.payload.item } : item
    ),
  };
};
 
const _updateTopPostItem = (state: PostsState, action: PostsAction): PostsState => {
  if (!action.payload) return state;
  return {
    ...state,
    topPostItems: state.topPostItems.map((item, idx) =>
      idx === action.payload.index ? { ...item, ...action.payload.item } : item
    ),
  };
};
 
const _resetPosts = (): PostsState => initialState;
 
type ReducerMap = {
  [key: string]: (state: PostsState, action: PostsAction) => PostsState;
};
 
const reducers: ReducerMap = {
  [fetchNewPosts.type]: _fetchPosts,
  [fetchTopPosts.type]: _fetchPosts,
  [fetchNewPostsSuccess.type]: _fetchNewPostsSuccess,
  [fetchTopPostsSuccess.type]: _fetchTopPostsSuccess,
  [fetchNewPostsFailure.type]: _fetchPostsFailure,
  [fetchTopPostsFailure.type]: _fetchPostsFailure,
  [loadNewPostItem.type]: _loadNewPostItem,
  [updateNewPostItem.type]: _updateNewPostItem,
  [loadTopPostItem.type]: _loadTopPostItem,
  [updateTopPostItem.type]: _updateTopPostItem,
  [resetPosts.type]: _resetPosts,
};
 
const postsReducer = (state = initialState, action: PostsAction): PostsState =>
  reducers[action.type] ? reducers[action.type](state, action) : state;
 
export default postsReducer;