diff --git a/client/src/store/action-creators/bookmark.ts b/client/src/store/action-creators/bookmark.ts index 4b1b0d2..f2a17e5 100644 --- a/client/src/store/action-creators/bookmark.ts +++ b/client/src/store/action-creators/bookmark.ts @@ -1,5 +1,8 @@ import axios from 'axios'; import { Dispatch } from 'redux'; +import { applyAuth } from '../../utility'; +import { ActionType } from '../action-types'; + import { ApiResponse, Bookmark, @@ -8,8 +11,7 @@ import { NewBookmark, NewCategory, } from '../../interfaces'; -import { applyAuth } from '../../utility'; -import { ActionType } from '../action-types'; + import { AddBookmarkAction, AddCategoryAction, @@ -17,6 +19,7 @@ import { DeleteCategoryAction, GetCategoriesAction, PinCategoryAction, + ReorderBookmarksAction, ReorderCategoriesAction, SetEditBookmarkAction, SetEditCategoryAction, @@ -339,3 +342,38 @@ export const setEditBookmark = payload: bookmark, }); }; + +export const reorderBookmarks = + (bookmarks: Bookmark[], categoryId: number) => + async (dispatch: Dispatch) => { + interface ReorderQuery { + bookmarks: { + id: number; + orderId: number; + }[]; + } + + try { + const updateQuery: ReorderQuery = { bookmarks: [] }; + + bookmarks.forEach((bookmark, index) => + updateQuery.bookmarks.push({ + id: bookmark.id, + orderId: index + 1, + }) + ); + + await axios.put>( + '/api/bookmarks/0/reorder', + updateQuery, + { headers: applyAuth() } + ); + + dispatch({ + type: ActionType.reorderBookmarks, + payload: { bookmarks, categoryId }, + }); + } catch (err) { + console.log(err); + } + }; diff --git a/client/src/store/action-types/index.ts b/client/src/store/action-types/index.ts index 81e1a84..80853c4 100644 --- a/client/src/store/action-types/index.ts +++ b/client/src/store/action-types/index.ts @@ -40,6 +40,7 @@ export enum ActionType { deleteBookmark = 'DELETE_BOOKMARK', updateBookmark = 'UPDATE_BOOKMARK', setEditBookmark = 'SET_EDIT_BOOKMARK', + reorderBookmarks = 'REORDER_BOOKMARKS', // AUTH login = 'LOGIN', logout = 'LOGOUT', diff --git a/client/src/store/actions/bookmark.ts b/client/src/store/actions/bookmark.ts index 60e7c9f..d9c89e8 100644 --- a/client/src/store/actions/bookmark.ts +++ b/client/src/store/actions/bookmark.ts @@ -66,3 +66,11 @@ export interface SetEditBookmarkAction { type: ActionType.setEditBookmark; payload: Bookmark | null; } + +export interface ReorderBookmarksAction { + type: ActionType.reorderBookmarks; + payload: { + bookmarks: Bookmark[]; + categoryId: number; + }; +} diff --git a/client/src/store/actions/index.ts b/client/src/store/actions/index.ts index 3193873..22d33d3 100644 --- a/client/src/store/actions/index.ts +++ b/client/src/store/actions/index.ts @@ -40,6 +40,7 @@ import { UpdateBookmarkAction, SetEditCategoryAction, SetEditBookmarkAction, + ReorderBookmarksAction, } from './bookmark'; import { @@ -85,6 +86,7 @@ export type Action = | DeleteBookmarkAction | UpdateBookmarkAction | SetEditBookmarkAction + | ReorderBookmarksAction // Auth | LoginAction | LogoutAction diff --git a/client/src/store/reducers/bookmark.ts b/client/src/store/reducers/bookmark.ts index d1fc380..3c069f0 100644 --- a/client/src/store/reducers/bookmark.ts +++ b/client/src/store/reducers/bookmark.ts @@ -24,32 +24,35 @@ export const bookmarksReducer = ( action: Action ): BookmarksState => { switch (action.type) { - case ActionType.getCategories: + case ActionType.getCategories: { return { ...state, loading: true, errors: undefined, }; + } - case ActionType.getCategoriesSuccess: + case ActionType.getCategoriesSuccess: { return { ...state, loading: false, categories: action.payload, }; + } - case ActionType.addCategory: + case ActionType.addCategory: { return { ...state, categories: [...state.categories, { ...action.payload, bookmarks: [] }], }; + } - case ActionType.addBookmark: + case ActionType.addBookmark: { const categoryIdx = state.categories.findIndex( (category) => category.id === action.payload.categoryId ); - const categoryWithNewBookmark = { + const targetCategory = { ...state.categories[categoryIdx], bookmarks: [...state.categories[categoryIdx].bookmarks, action.payload], }; @@ -58,67 +61,71 @@ export const bookmarksReducer = ( ...state, categories: [ ...state.categories.slice(0, categoryIdx), - categoryWithNewBookmark, + targetCategory, ...state.categories.slice(categoryIdx + 1), ], - categoryInEdit: categoryWithNewBookmark, + categoryInEdit: targetCategory, }; + } - case ActionType.pinCategory: - const pinnedCategoryIdx = state.categories.findIndex( + case ActionType.pinCategory: { + const categoryIdx = state.categories.findIndex( (category) => category.id === action.payload.id ); return { ...state, categories: [ - ...state.categories.slice(0, pinnedCategoryIdx), + ...state.categories.slice(0, categoryIdx), { ...action.payload, - bookmarks: [...state.categories[pinnedCategoryIdx].bookmarks], + bookmarks: [...state.categories[categoryIdx].bookmarks], }, - ...state.categories.slice(pinnedCategoryIdx + 1), + ...state.categories.slice(categoryIdx + 1), ], }; + } - case ActionType.deleteCategory: - const deletedCategoryIdx = state.categories.findIndex( + case ActionType.deleteCategory: { + const categoryIdx = state.categories.findIndex( (category) => category.id === action.payload ); return { ...state, categories: [ - ...state.categories.slice(0, deletedCategoryIdx), - ...state.categories.slice(deletedCategoryIdx + 1), + ...state.categories.slice(0, categoryIdx), + ...state.categories.slice(categoryIdx + 1), ], }; + } - case ActionType.updateCategory: - const updatedCategoryIdx = state.categories.findIndex( + case ActionType.updateCategory: { + const categoryIdx = state.categories.findIndex( (category) => category.id === action.payload.id ); return { ...state, categories: [ - ...state.categories.slice(0, updatedCategoryIdx), + ...state.categories.slice(0, categoryIdx), { ...action.payload, - bookmarks: [...state.categories[updatedCategoryIdx].bookmarks], + bookmarks: [...state.categories[categoryIdx].bookmarks], }, - ...state.categories.slice(updatedCategoryIdx + 1), + ...state.categories.slice(categoryIdx + 1), ], }; + } - case ActionType.deleteBookmark: - const categoryInUpdateIdx = state.categories.findIndex( + case ActionType.deleteBookmark: { + const categoryIdx = state.categories.findIndex( (category) => category.id === action.payload.categoryId ); const targetCategory = { - ...state.categories[categoryInUpdateIdx], - bookmarks: state.categories[categoryInUpdateIdx].bookmarks.filter( + ...state.categories[categoryIdx], + bookmarks: state.categories[categoryIdx].bookmarks.filter( (bookmark) => bookmark.id !== action.payload.bookmarkId ), }; @@ -126,69 +133,88 @@ export const bookmarksReducer = ( return { ...state, categories: [ - ...state.categories.slice(0, categoryInUpdateIdx), + ...state.categories.slice(0, categoryIdx), targetCategory, - ...state.categories.slice(categoryInUpdateIdx + 1), + ...state.categories.slice(categoryIdx + 1), ], categoryInEdit: targetCategory, }; + } - case ActionType.updateBookmark: - const parentCategoryIdx = state.categories.findIndex( + case ActionType.updateBookmark: { + const categoryIdx = state.categories.findIndex( (category) => category.id === action.payload.categoryId ); - const updatedBookmarkIdx = state.categories[ - parentCategoryIdx - ].bookmarks.findIndex((bookmark) => bookmark.id === action.payload.id); + const bookmarkIdx = state.categories[categoryIdx].bookmarks.findIndex( + (bookmark) => bookmark.id === action.payload.id + ); - const categoryWithUpdatedBookmark = { - ...state.categories[parentCategoryIdx], + const targetCategory = { + ...state.categories[categoryIdx], bookmarks: [ - ...state.categories[parentCategoryIdx].bookmarks.slice( - 0, - updatedBookmarkIdx - ), + ...state.categories[categoryIdx].bookmarks.slice(0, bookmarkIdx), action.payload, - ...state.categories[parentCategoryIdx].bookmarks.slice( - updatedBookmarkIdx + 1 - ), + ...state.categories[categoryIdx].bookmarks.slice(bookmarkIdx + 1), ], }; return { ...state, categories: [ - ...state.categories.slice(0, parentCategoryIdx), - categoryWithUpdatedBookmark, - ...state.categories.slice(parentCategoryIdx + 1), + ...state.categories.slice(0, categoryIdx), + targetCategory, + ...state.categories.slice(categoryIdx + 1), ], - categoryInEdit: categoryWithUpdatedBookmark, + categoryInEdit: targetCategory, }; + } - case ActionType.sortCategories: + case ActionType.sortCategories: { return { ...state, categories: sortData(state.categories, action.payload), }; + } - case ActionType.reorderCategories: + case ActionType.reorderCategories: { return { ...state, categories: action.payload, }; + } - case ActionType.setEditCategory: + case ActionType.setEditCategory: { return { ...state, categoryInEdit: action.payload, }; + } - case ActionType.setEditBookmark: + case ActionType.setEditBookmark: { return { ...state, bookmarkInEdit: action.payload, }; + } + + case ActionType.reorderBookmarks: { + const categoryIdx = state.categories.findIndex( + (category) => category.id === action.payload.categoryId + ); + + return { + ...state, + categories: [ + ...state.categories.slice(0, categoryIdx), + { + ...state.categories[categoryIdx], + bookmarks: action.payload.bookmarks, + }, + ...state.categories.slice(categoryIdx + 1), + ], + }; + } default: return state;