Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

[FE] feat: 카테고리 및 글 드래그앤드롭 기능 구현 #418

Merged
merged 25 commits into from
Sep 20, 2023
Merged
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
19497a7
refactor: 카테고리 데이터가 null 인 경우 early return
nangkyeonglim Sep 12, 2023
543cb3b
feat: 글 및 카테고리 순서 수정 API, 훅 작성
nangkyeonglim Sep 16, 2023
27b6e00
feat: 타입 가드 유틸 함수 구현
nangkyeonglim Sep 16, 2023
d0f32bc
feat: 글 및 카테고리 순서 수정 API mocking
nangkyeonglim Sep 16, 2023
3a8269b
feat: 카테고리에 스크롤이 생길 때 `Header`가 고정되도록 수정
nangkyeonglim Sep 16, 2023
925a694
feat: 스크롤이 있을 때 카테고리 추가 시 맨 아래로 스크롤 되는 기능 구현
nangkyeonglim Sep 16, 2023
bd56b74
design: 카테고리 및 글 hover시 색상 변경
nangkyeonglim Sep 16, 2023
8d6cfe0
feat: `throttle` 유틸 함수 구현
nangkyeonglim Sep 16, 2023
1d007d3
feat: 같은 배열인지 확인하는 유틸 함수 작성
nangkyeonglim Sep 16, 2023
82c9fc2
feat: useDragAndDrop 훅 작성
nangkyeonglim Sep 16, 2023
eace190
feat: 카테고리 드래그 앤 드롭 구현
nangkyeonglim Sep 16, 2023
1d30e31
feat: 글 드래그 앤 드롭 구현
nangkyeonglim Sep 16, 2023
3dc15b3
feat: 드래그 영역 확장 및 throttle 적용
nangkyeonglim Sep 16, 2023
efb4468
refactor: `useDragAndDrop` 훅 파일 이동
nangkyeonglim Sep 16, 2023
16e602c
fix: dragEnd 시 버블링으로 인해 2번 API 요청 되는 현상 수정
nangkyeonglim Sep 19, 2023
fea808c
refactor: 카테고리 순서 변경 시 테이블 페이지의 글을 받아오는 쿼리 무효화 제거
nangkyeonglim Sep 19, 2023
5f4d2a4
refactor: 드래그 종류 확인 함수를 값으로 변경하고 네이밍 수정
nangkyeonglim Sep 19, 2023
7df8f3c
refactor: 마지막 드래그 영역 아이디 상수화
nangkyeonglim Sep 19, 2023
354e868
refactor: 드래그 영역 색 상수화
nangkyeonglim Sep 19, 2023
cb5f0bc
docs: 동작 이해를 위한 주석 추가
nangkyeonglim Sep 19, 2023
c24e73b
refactor: 기본 카테고리 id 로컬스토리지에서 받아오도록 변경
nangkyeonglim Sep 19, 2023
6db984a
refactor: `decideDraggingTarget` 조건문 분리
nangkyeonglim Sep 19, 2023
0baaa73
refactor: `handleDragStart` 버블링 막는 조건문 변경
nangkyeonglim Sep 19, 2023
56c03f6
refactor: 드래그 위치 인덱스 상수화
nangkyeonglim Sep 19, 2023
2939b6f
refactor: 드래그 불가한 조건문 명확하게 변경
nangkyeonglim Sep 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 51 additions & 4 deletions frontend/src/components/Category/WritingList/WritingList.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,54 @@
import { WritingIcon } from 'assets/icons';
import { usePageNavigate } from 'hooks/usePageNavigate';
import { useParams } from 'react-router-dom';
import { styled } from 'styled-components';
import { styled, css } from 'styled-components';
import { useWritings } from './useWritings';
import DeleteButton from 'components/DeleteButton/DeleteButton';
import { useDeleteWritings } from './useDeleteWritings';
import { DragEvent } from 'react';
import { LAST_DRAG_SECTION_ID } from 'constants/drag';

type Props = {
categoryId: number;
isOpen: boolean;
dragOverIndexList: number[];
onDragStart: (...ids: number[]) => (e: DragEvent) => void;
onDragEnter: (...ids: number[]) => (e: DragEvent) => void;
onDragEnd: (e: DragEvent) => void;
isWritingDrag: () => boolean;
};

const WritingList = ({ categoryId, isOpen }: Props) => {
const WritingList = ({
categoryId,
isOpen,
dragOverIndexList,
onDragStart,
onDragEnter,
onDragEnd,
isWritingDrag,
}: Props) => {
const { goWritingPage } = usePageNavigate();
const { writings } = useWritings(categoryId, isOpen);
const writingId = Number(useParams()['writingId']);
const deleteWritings = useDeleteWritings();

const isWritingDragOverTarget = (categoryId: number, writingId: number) =>
isWritingDrag() && categoryId === dragOverIndexList[0] && writingId === dragOverIndexList[1];

if (!writings || writings?.length === 0) return <S.NoWritingsText>빈 카테고리</S.NoWritingsText>;

return (
<ul>
{writings.map((writing) => (
<S.Item key={writing.id} $isClicked={writingId === writing.id}>
<S.Item
key={writing.id}
$isClicked={writingId === writing.id}
$isDragOverTarget={isWritingDragOverTarget(categoryId, writing.id)}
draggable={true}
onDragStart={onDragStart(categoryId, writing.id)}
onDragEnter={onDragEnter(categoryId, writing.id)}
onDragEnd={onDragEnd}
>
<S.Button
aria-label={`${writing.title}글 메인화면에 열기`}
onClick={() => goWritingPage({ categoryId, writingId: writing.id })}
Expand All @@ -37,22 +63,33 @@ const WritingList = ({ categoryId, isOpen }: Props) => {
</S.DeleteButtonWrapper>
</S.Item>
))}
<S.DragLastSection
onDragEnter={onDragEnter(categoryId, LAST_DRAG_SECTION_ID)}
$isDragOverTarget={isWritingDragOverTarget(categoryId, LAST_DRAG_SECTION_ID)}
/>
</ul>
);
};

export default WritingList;

const S = {
Item: styled.li<{ $isClicked: boolean }>`
Item: styled.li<{ $isClicked: boolean; $isDragOverTarget: boolean }>`
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 3.6rem;
border-radius: 4px;
background-color: ${({ theme, $isClicked }) => $isClicked && theme.color.gray4};
border-top: 0.4rem solid transparent;

${({ $isDragOverTarget }) =>
$isDragOverTarget &&
css`
border-radius: 0;
border-top: 0.4rem solid #2383e26e;
yogjin marked this conversation as resolved.
Show resolved Hide resolved
`};
&:hover {
background-color: ${({ theme }) => theme.color.gray3};

Expand Down Expand Up @@ -98,4 +135,14 @@ const S = {
display: none;
margin-right: 0.8rem;
`,

DragLastSection: styled.div<{ $isDragOverTarget: boolean }>`
height: 0.4rem;
background-color: transparent;
${({ $isDragOverTarget }) =>
$isDragOverTarget &&
css`
background-color: #2383e26e;
`};
`,
};