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;
|