diff --git a/__mocks__/handlers/boardHandlers.ts b/__mocks__/handlers/boardHandlers.ts index 61651fe..9251848 100644 --- a/__mocks__/handlers/boardHandlers.ts +++ b/__mocks__/handlers/boardHandlers.ts @@ -44,6 +44,16 @@ const boardsInfo: BoardsInfo = { boardTitle: '공지사항', boardIndex: 0, }, + { + boardId: 'bbb', + boardTitle: '게임 룰', + boardIndex: 1, + }, + { + boardId: 'ccc', + boardTitle: '커뮤니티', + boardIndex: 2, + }, ], '234': [ { diff --git a/src/components/Sidebar/BoardBar/BoardBody.tsx b/src/components/Sidebar/BoardBar/BoardBody.tsx index 7407678..dc6a8c0 100644 --- a/src/components/Sidebar/BoardBar/BoardBody.tsx +++ b/src/components/Sidebar/BoardBar/BoardBody.tsx @@ -1,3 +1,4 @@ +import { DragDropContext, Droppable, Draggable, DropResult } from '@hello-pangea/dnd'; import { MouseEventHandler, useEffect, useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { useRouter } from 'next/router'; @@ -44,6 +45,7 @@ const postData = async (channelLink: string) => { const BoardBody = ({ channelLink }: Props) => { const [selected, setSelected] = useState(''); + const [boards, setBoards] = useState(); const router = useRouter(); const { data, isSuccess } = useQuery(['getBoardLists', channelLink], () => @@ -71,24 +73,51 @@ const BoardBody = ({ channelLink }: Props) => { }; const onClickNewBoard: MouseEventHandler = async () => { + if (boards === undefined) return; const res = await postData(channelLink); const newBoard: Channels = { boardId: res.boardId.toString(), boardTitle: res.boardTitle, boardIndex: res.boardIndex, }; - data?.push(newBoard); + setBoards([...boards, newBoard]); selectBoardId(newBoard.boardId); handleBoard(channelLink, newBoard.boardId, res.boardTitle); }; + const postCustomBoard = async (customedBoards: Channels[]) => { + const res = await authAPI({ + method: 'post', + url: `/api/channel/${channelLink}/order`, + data: { + channelBoardLoadDtoList: boards, + }, + }); + + if (res.status === 200) setBoards(customedBoards); + }; + const selectBoardId = (boardId: string) => { router.push(`/contents/${channelLink}/${boardId}`); setSelected(boardId); }; + const dragEnd = ({ source, destination }: DropResult) => { + if (!destination || !boards) return; + if (source.index === destination.index) return; + + const newBoards = [...boards]; + const [removed] = newBoards.splice(source.index, 1); + newBoards.splice(destination.index, 0, removed); + for (let i = 0; i < newBoards.length; i++) { + newBoards[i].boardIndex = i; + } + postCustomBoard(newBoards); + }; + useEffect(() => { const lastVisitBoardId = lastVisitedBoardIdLists[channelLink]?.boardId; + if (isSuccess) setBoards(data); if (lastVisitBoardId) { selectBoardId(lastVisitBoardId); @@ -103,26 +132,51 @@ const BoardBody = ({ channelLink }: Props) => { return ( - {isSuccess && - data.map((board) => ( - - {board.boardTitle} - - - ))} - {channelPermission === 0 && ( - - 공지 추가하기 - - - )} - + + + {(provided) => ( +
+ {boards && + boards.map((board, index) => + channelPermission === 0 ? ( + + {(provided) => ( + + {board.boardTitle} + + + )} + + ) : ( + + {board.boardTitle} + + ), + )} + {channelPermission === 0 && ( + + 공지 추가하기 + + + )} +
+ )} +
+
); @@ -144,6 +198,7 @@ const Wrapper = styled.li<{ isSelected: boolean }>` &:hover { background-color: #39587e; } + color: white; ${({ isSelected }) => isSelected && `background-color: #39587E`}; `;