Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#54] Drag & Drop UI 구현 #55

Merged
merged 30 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a567ce6
feat : 이것저것 ..
youdame Jan 2, 2024
f5512e6
feat : 추가적 구현
youdame Jan 2, 2024
45ebcb5
feat(input disabled) : 인풋 값이 충족되지 않았을 때 disabled 로직 넣어줌
ayden94 Jan 2, 2024
37f7b6d
feat() : 추가
ayden94 Jan 2, 2024
23518da
feat()
ayden94 Jan 2, 2024
39ab817
feat(mydashboard) : 리다이렉션 기능 구현
ayden94 Jan 2, 2024
2edc94f
Co-authored-by: haneul-kimm <han-kimm@users.noreply.github.com>
ayden94 Jan 2, 2024
d28de4b
feat: 디너쇼 1부
han-kimm Jan 2, 2024
3579ebd
feat(무한 스크롤) : 구현
ayden94 Jan 2, 2024
b53fb51
feat(column.tsx) : 카드 무한 스크롤 구현
ayden94 Jan 2, 2024
6ba5b8a
feat : 대시보드 초대 취소, 대시보드 멤버 삭제 기능 구현
youdame Jan 2, 2024
73a1bbe
feat : 반응형 구현
youdame Jan 2, 2024
c7c8f25
feat (무한스크롤): fetch -> sender
han-kimm Jan 3, 2024
d8977d1
feat (초대받은 목록) 무한스크롤
han-kimm Jan 3, 2024
c3c721a
feat (TabalScroll.tsx) : 무한스크롤 구현
han-kimm Jan 3, 2024
1d9ce0f
feat: 커밋
han-kimm Jan 3, 2024
f5ab1aa
feat : 런치쇼
youdame Jan 3, 2024
687efbe
feat : 모달 바깥 부분 클릭시 모달 닫히기 구현 중 및 드래그 앤 드롭 라이브러리 설치
youdame Jan 3, 2024
b82e3b6
feat: 드래그앤드롭 구현중
han-kimm Jan 3, 2024
adb7645
feat : 모달 바깥부분 클릭 시 닫힘 기능 구현
youdame Jan 3, 2024
bc44506
feat : 자신이 쓴 댓글이 아니면 수정 삭제 기능 안 보이게 구현
youdame Jan 3, 2024
4c4b008
feat : ESC 키 누르면 모달 닫기 기능 구현
youdame Jan 3, 2024
c51d1be
Merge branch 'page/co_op' of https://github.com/harigari/taskify into…
han-kimm Jan 3, 2024
8d193a2
feat: 드래그앤드롭~ 핸들러 함수 작성
han-kimm Jan 3, 2024
fccbd0d
feat: 드래그앤드랍~ 아직 put 메서드 실행안함
han-kimm Jan 3, 2024
171a5da
feat: 드래그앤드롭 완성
han-kimm Jan 3, 2024
bb50263
feat (useDragScroll) : 마우스클릭으로 터치스와이핑 구현
han-kimm Jan 3, 2024
39e17b5
feat (useDragScroll) : 카드 이동 시 좌우 스크롤 중지
han-kimm Jan 3, 2024
db582ac
feat: Card 반응형 css 수정
han-kimm Jan 4, 2024
46fcc53
fix: 카드 생성 시 동기화 안되는 오류 수정
han-kimm Jan 4, 2024
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
18 changes: 6 additions & 12 deletions apis/sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,8 @@ class Api {
if (typeof result === "string") {
return result;
}
if (typeof result === "function" && "dashboardId" in obj) {
return result(obj.dashboardId, obj.invitationId);
}
if (typeof result === "function" && "id" in obj) {
return result(obj.id);
}
if (typeof result === "function" && "method" in obj) {
return result(obj.method);
if (typeof result === "function") {
return result(obj);
Comment on lines +16 to +17
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sender 내부에서 makeUrl 함수를 호출 할 때 각각의 파라미터 순서를 지키는게 불편해서
객체로 받아서 내부에서 처리하도록 했습니다~

}
};

Expand All @@ -47,7 +41,7 @@ class Api {
},
});
const data = await res.json();
return { status: res.status, data };
return { status: res.status, data, message: data.message };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서버에서 오류 메시지가 있을 경우, 메시지를 담는 속성을 추가해두었습니다.

};

put: HTTP<"put"> = async (obj) => {
Expand All @@ -59,11 +53,11 @@ class Api {
});

if (res.status === 204) {
return { status: res.status, data: null };
return { status: res.status, data: null as any };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete 일때는 데이터가 안 담겨져서 오는데 data 속성을 null 로 해도 타입 통과가 안돼서, 일단은 any 선언했습니다.

}

const data = await res.json();
return { status: res.status, data };

return { status: res.status, data, message: data.message };
};

delete: HTTP<"delete"> = async (obj) => {
Expand Down
43 changes: 37 additions & 6 deletions components/Card/Card.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
}

.cardCountWrapper {
display: flex;
justify-content: center;
align-items: center;
padding: 0.4rem 0.6rem;
width: fit-content;
height: 2rem;
Expand Down Expand Up @@ -92,32 +95,44 @@
.cardContainer {
flex-direction: row;
align-items: center;
gap: 2rem;
}
.imageContent {
width: 11rem;

.imageWrapper {
width: 100%;
height: auto;
}
Comment on lines +101 to 104
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

카드에 담긴 imge를 반응형으로 창 크기에 따라서 너비가 커지게 만들었습니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

화긴요


.allContentContainer {
align-items: center;
flex-direction: row;
}

.cardTagsWrapper {
justify-content: start;
max-width: 20rem;
}

.cardTagCotainer {
margin-right: 1.6rem;
}

.cardCountWrapper {
display: none;
}

.cardInfoWrapper {
justify-content: space-between;
margin-top: 0;
}

.imageWrapper {
max-width: 50%;
}

.imageWrapper img {
width: 9.08rem;
height: 5.3rem;
width: 100%;
height: 8em;
}
}

Expand All @@ -127,43 +142,59 @@
align-items: flex-start;
width: 100%;
}

.cardContentContainer {
width: 100%;
}

.imageContent {
width: 26rem;
height: 15.2rem;
}

.allContentContainer {
flex-direction: column;
align-items: flex-start;
}

.cardTitleWrapper {
font-size: 1.4rem;
}

.cardTagCotainer {
margin: 0;
width: 100%;
gap: 0.8rem;
}

.dateIcon {
width: 1.4rem;
height: 1.4rem;
}

.date {
font-size: 1rem;
}

.cardInfoWrapper {
width: 100%;
}

.cardTagsWrapper {
max-width: 100%;
}

.cardCountWrapper {
display: flex;
}

.imageWrapper {
width: 100%;
max-width: 100%;
}

.imageWrapper img {
width: 26rem;
height: 15.2rem;
width: 100%;
height: 20rem;
}
}
116 changes: 64 additions & 52 deletions components/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import ProfileIcon from "@/components/Members/ProfileIcon";
import { CardData } from "@/types/api.type";
import { CardData, EntireData } from "@/types/api.type";
import Image from "next/image";
import ChipTag from "../Chips/ChipTag/ChipTag";
import styles from "./Card.module.css";
import formatDateString from "@/utils/formatDateString";
import { Dispatch, SetStateAction, useState } from "react";
import TaskCardModal from "@/modals/TaskCardModal";
import { Draggable } from "@hello-pangea/dnd";

interface CardProps {
data: CardData;
index: number;
columnTitle: string;
setCardList: Dispatch<SetStateAction<CardData[]>>;
setEntireList: Dispatch<SetStateAction<EntireData>>;
}

const Card = ({ data, columnTitle, setCardList }: CardProps) => {
const Card = ({ data, index, columnTitle, setEntireList }: CardProps) => {
const [isCardModalOpen, setIsCardModalOpen] = useState(false);
const { slicedTagList, etc } = tagSlicer(data.tags);

Expand All @@ -22,60 +24,70 @@ const Card = ({ data, columnTitle, setCardList }: CardProps) => {
};

return (
<>
<div className={styles.cardContainer} onClick={handleCardModalToggle}>
{/* 카드 이미지 */}
{data.imageUrl && (
<div className={styles.imageWrapper}>
<Image width={274} height={160} className={styles.imageContent} src={data.imageUrl} alt="카드" />
</div>
)}
{/* 카드 내용 */}
<div className={styles.cardContentContainer}>
{/* 카드 제목 */}
<span className={styles.cardTitleWrapper}>{data.title}</span>
<div className={styles.allContentContainer}>
{/* 카드 태그들 */}
<div className={styles.cardTagContainer}>
<div className={styles.cardTagsWrapper}>
{slicedTagList.map((tag: string) => (
<ChipTag size="sm" key={tag}>
{tag}
</ChipTag>
))}
<Draggable draggableId={String(data.id)} index={index}>
{(provided) => (
<>
<article
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
className={styles.cardContainer}
onClick={handleCardModalToggle}
>
{/* 카드 이미지 */}
{data.imageUrl && (
<div className={styles.imageWrapper}>
<Image width={274} height={160} className={styles.imageContent} src={data.imageUrl} alt="카드" />
</div>
{etc > 0 && (
<div className={styles.cardCountWrapper}>
<span>그 외 {etc}개</span>
)}
{/* 카드 내용 */}
<div className={styles.cardContentContainer}>
{/* 카드 제목 */}
<span className={styles.cardTitleWrapper}>{data.title}</span>
<div className={styles.allContentContainer}>
{/* 카드 태그들 */}
<div className={styles.cardTagContainer}>
<div className={styles.cardTagsWrapper}>
{slicedTagList.map((tag: string) => (
<ChipTag size="sm" key={tag}>
{tag}
</ChipTag>
))}
</div>
{etc > 0 && (
<div className={styles.cardCountWrapper}>
<span>그 외 {etc}개</span>
</div>
)}
</div>
{/* 카드 하단 날짜, 지정자 */}
<div className={styles.cardInfoWrapper}>
<div className={styles.dateWrapper}>
<Image
className={styles.dateIcon}
src="/icons/icon-calendar.svg"
alt="Calendar Icon"
width={20}
height={20}
/>
<span className={styles.date}>{formatDateString(data.dueDate, "KOREA", "yyyy.MM.dd")}</span>
</div>
<ProfileIcon member={data.assignee} size="sm" />
</div>
)}
</div>
{/* 카드 하단 날짜, 지정자 */}
<div className={styles.cardInfoWrapper}>
<div className={styles.dateWrapper}>
<Image
className={styles.dateIcon}
src="/icons/icon-calendar.svg"
alt="Calendar Icon"
width={20}
height={20}
/>
<span className={styles.date}>{formatDateString(data.dueDate, "KOREA", "yyyy.MM.dd")}</span>
</div>
<ProfileIcon member={data.assignee} size="sm" />
</div>
</div>
</div>
</div>
{isCardModalOpen && (
<TaskCardModal
data={data}
columnTitle={columnTitle}
handleModalClose={handleCardModalToggle}
setCardList={setCardList}
/>
</article>
{isCardModalOpen && (
<TaskCardModal
data={data}
columnTitle={columnTitle}
handleModalClose={handleCardModalToggle}
setEntireList={setEntireList}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 결국 그럼 모든 컬럼에 있는 모든 카드를 하나의 스테이트에서 가져오기로 한 거군요

/>
)}
</>
)}
</>
</Draggable>
);
};

Expand Down
4 changes: 2 additions & 2 deletions components/Chips/ChipColor/ChipColor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface ChipColorProps {
const ChipColor = ({ size, color, onClick, isSelected }: ChipColorProps) => {
return (
<>
<button
<div
className={clsx(
style.container,
{ [style.large]: size === "lg" },
Expand All @@ -26,7 +26,7 @@ const ChipColor = ({ size, color, onClick, isSelected }: ChipColorProps) => {
>
{/* 크기에 따라 check.svg 변경 */}
{isSelected ? <Image width={22} height={22} src="/icons/icon-check.svg" alt="선택된 태그" /> : null}
</button>
</div>
</>
);
};
Expand Down
7 changes: 0 additions & 7 deletions components/Chips/ChipColors/ChipColors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@ import style from "./ChipColors.module.css";
import ChipColor from "../ChipColor/ChipColor";
import { ColorType } from "@/types/api.type";

// interface ChipColorProps {
// size: string;
// color: "green" | "purple" | "orange" | "blue" | "pink";
// onClick?: () => void;
// isSelected: boolean;
// }

interface ChipColorsProps {
selectedColor: ColorType;
setSelectedColor: Dispatch<SetStateAction<ColorType>>;
Expand Down
2 changes: 1 addition & 1 deletion components/Chips/ChipTodo/ChipTodo.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

/* 화이트 버전일 때 */
.white {
background-color: white;
background-color: var(--gray10);
}

.whiteText {
Expand Down
12 changes: 5 additions & 7 deletions components/Column/Column.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
display: flex;
flex-direction: column;
padding: 2rem;
width: 35.4rem;
height: auto;
border-right: 1px solid var(--gray20);
border-right: 0.1rem solid var(--gray20);
background-color: var(--gray10);
cursor: pointer;
width: 36rem;
}

.headerContainer {
Expand Down Expand Up @@ -36,7 +34,7 @@
align-items: center;
justify-content: center;
flex-shrink: 0;
border: 1px solid var(--gray30);
border: 0.1rem solid var(--gray30);
width: 100%;
height: 4rem;
background: var(--white);
Expand All @@ -49,7 +47,7 @@
flex-direction: column;
}
.totalContainer {
width: 58.4rem;
width: 100%;
border-bottom: 1px solid var(--gray20);
border-right: none;
}
Expand All @@ -61,7 +59,7 @@
}
.totalContainer {
flex-direction: column;
width: 30.8rem;
width: 100%;
margin-bottom: 1.2rem;
stroke-width: 1px;
stroke: var(--gray-gray_EEEEEE, #eee);
Expand Down
Loading