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

[김유경] Week21 #1090

Open
wants to merge 65 commits into
base: part3-김유경
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
dc12647
🔥 Delete : delete unnecessary files
codingaring May 9, 2024
14eb7b6
✨ Faet : add handleToken function
codingaring May 9, 2024
a50c45d
♻️ Refactor : refactor getCategory function
codingaring May 9, 2024
f8fbe8b
🚚 Rename : data -> folderInfo
codingaring May 9, 2024
31491e5
✨ Feat : install react-query
codingaring May 9, 2024
511db2a
✨ Feat : use react-query
codingaring May 9, 2024
5cd40de
✏️ Fix : 페이지 첫 로드시, 카테고리 목록이 안뜨던 문제 해결
codingaring May 9, 2024
ca8145c
🚚 Rename : AddFolderContent -> AddFolder
codingaring May 9, 2024
44cebb4
✨ feat : add customhook : useModal
codingaring May 9, 2024
386a2e2
♻️ Refactor : modal change AddToFolderModal
codingaring May 9, 2024
8248ffb
💄 UI : modify addToFolder Button text 삭제하기 -> 추가하기
codingaring May 9, 2024
39b93fb
♻️ Refactor : completed Modal Refactor
codingaring May 9, 2024
bee3b7e
🐛 Fix : disabled kebab button in folder page
codingaring May 9, 2024
ab543d3
♻️ Refactor : changeModal Button
codingaring May 9, 2024
10950ac
💄 style : extends PrimaryButton to AddToFolderButton
codingaring May 9, 2024
c5a0a45
✨ Feat : posible rename Modal
codingaring May 9, 2024
35f7adc
✨ Feat : createFolder
codingaring May 10, 2024
f5c866d
✨ Feat : add postAddToFolder
codingaring May 10, 2024
345513f
🐛Fix : 폴더 데이터가 안불러와지던 문제 해결
codingaring May 10, 2024
fc2cb45
🐛 Fix : 링크 목록이 보이지 않던 문제 해결
codingaring May 10, 2024
590111b
✨ Feat : change API url
codingaring May 10, 2024
5f637c9
✨ Feat : sharedPage change API function
codingaring May 11, 2024
be5db32
✨ Feat : folderPage data api change
codingaring May 11, 2024
40d9659
✨ Feat : add function deleteFolder Modal
codingaring May 11, 2024
43b5bf7
✨ Feat : deleteLink
codingaring May 11, 2024
7e17707
♻️ Refactor : change signin api url and modify handleToken
codingaring May 12, 2024
64c61be
♻️ Refactor : modify change api url : checkSignin
codingaring May 12, 2024
b4a2da1
♻️ Refactor : change signup api url
codingaring May 12, 2024
d99735f
♻️ Refactor : change currentUserProfile api url
codingaring May 12, 2024
8f92b5d
💚 Build : resolved build error
codingaring May 12, 2024
e1c5d03
♻️ Refactor : modify landing header button event
codingaring May 12, 2024
fd3e932
♻️ Refactor : change fetch -> mutation
codingaring May 12, 2024
a230069
♻️ Refactor : change modal event type
codingaring May 12, 2024
97225a8
🐛 Fix & Refactor : modify prop and type and arguments
codingaring May 17, 2024
4d6f407
🐛 Fix : modify Navigation Bar profile state initialValue
codingaring May 17, 2024
f6bb994
♻️ Refactor : modify router url
codingaring May 17, 2024
0edfd94
♻️ Fix : resole error
codingaring May 17, 2024
6924ca3
🐛 Fix : resolve conflict
codingaring May 17, 2024
3b028ab
🐛 fix : modify router url
codingaring May 17, 2024
467675b
♻️ Refactor : modify modal event type
codingaring May 17, 2024
a9afb09
🎨 Design : add scroll folder Category
codingaring May 17, 2024
2ab550a
🎨 Design : Empty cardList position : static -> absolute
codingaring May 17, 2024
1707116
♻️ Refactor : add invalidateQueries addFolderModal
codingaring May 17, 2024
2fcce17
♻️ Refactor : add invalidateQueries deleteFolderModal
codingaring May 17, 2024
e0a887a
♻️ Refactor : add invalidateQueries in addToFolder
codingaring May 17, 2024
5cfae1a
♻️ Refactor : add invalidateQueries renameModal
codingaring May 17, 2024
ed70b60
♻️ Refactor : Functional update usePortalContents
codingaring May 17, 2024
34d3ffa
♻️ refactor : modify initialValue and remove unnecessary value
codingaring May 17, 2024
963a74a
remove unnecessary files
codingaring May 17, 2024
d600a2e
🐛 Fix : resolve import error
codingaring May 17, 2024
9b2ba6d
✨ Feat : add wishList API function
codingaring May 17, 2024
33b7f50
✨ Feat : add wishList function
codingaring May 18, 2024
d2ef71f
💄 styled : modify styled components
codingaring May 18, 2024
053cadd
💄 style : modify styled components
codingaring May 18, 2024
aae0342
🚚 Rename : rename data -> folderNameList
codingaring May 18, 2024
5199740
♻️ Refactor : add createHttpClient
codingaring May 21, 2024
da6f616
🚧work : modify base URL
codingaring May 21, 2024
3626d2c
🐛 Fix : resolve data fetch error
codingaring May 21, 2024
1486988
🐛 Fix : resolve shared page error
codingaring May 21, 2024
d2529b8
🛂 Authorization : check validateAccessToken
codingaring May 27, 2024
deaeb35
♻️ Refactor : add authAPI
codingaring May 27, 2024
460fade
🔧 Chore : add eslint, prettier files
codingaring May 27, 2024
3477de0
🐛 Fix : resolve build error
codingaring May 27, 2024
c97a5ce
♻️ Refactor : add AddToFolder else if
codingaring May 28, 2024
711d90f
♻️ Refactor : handleToken window === undefined , throw error
codingaring May 28, 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
34 changes: 18 additions & 16 deletions components/common/CardContent/CardContent.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { KebabMenu } from "@components/folder/KebabMenu/KebabMenu";
import * as S from "./CardContentStyled";
import { MouseEvent, useState } from "react";
import { FolderListDataForm } from "../../../types/DataForm";
import Image from "next/image";
import { usePortalContents } from "@hooks/usePortalContents";
import { FolderListDataForm } from "@data-access/getCategory";

interface CardContentProps {
elapsedTime: string;
Expand All @@ -11,6 +11,8 @@ interface CardContentProps {
isHovered: boolean;
currentLocation: string;
selectURL: string;
folderList: FolderListDataForm[];
linkId: number;
}

export const CardContent = ({
Expand All @@ -20,28 +22,28 @@ export const CardContent = ({
isHovered,
currentLocation,
selectURL,
folderList,
linkId,
}: CardContentProps) => {
const [isOpened, setIsClick] = useState(false);
const className = isHovered
? "CardContent CardContent-hovered"
: "CardContent";

const handleClickMenu = (e: MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
setIsClick(isOpened === false ? true : false);
};
const kebabMenu = usePortalContents();

return (
<S.CardContentContainer isHovered={isHovered}>
<div className="CardContent-time-kebab">
<>
<S.ElapsedTime>{elapsedTime}</S.ElapsedTime>
{currentLocation === "/folder" && (
<S.KebabButton type="button" onClick={handleClickMenu}>
{!currentLocation.includes("shared") && (
<S.KebabButton type="button" onClick={kebabMenu.toggleContents}>
<Image fill src="/images/kebab.svg" alt="메뉴 보기" />
</S.KebabButton>
)}
{isOpened && <KebabMenu selectURL={selectURL} />}
</div>
{kebabMenu.isOpenModal && (
<KebabMenu
folderList={folderList}
selectURL={selectURL}
linkId={linkId}
/>
)}
</>

<S.Description>{description}</S.Description>
<S.CreatedAtText>{createdAt}</S.CreatedAtText>
Expand Down
14 changes: 13 additions & 1 deletion components/common/CardItem/CardItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export const CardItem = ({
image_source,
description,
created_at,
folderList,
linkId,
favorite,
folderId,
}: CardInfoDataForm) => {
const [isHovered, setIsHovered] = useState(false);
const location = useRouter();
Expand All @@ -26,14 +30,22 @@ export const CardItem = ({
<a href={url} target="_blank" rel="noopener noreferrer">
<Card onMouseOver={handleMouseOver} onMouseLeave={handleMouseLeave}>
<CardImage imageSource={image_source} isZoomedIn={isHovered} />
{currentLocation === "/folder" && <WishListButton />}
{currentLocation.includes("folder") && (
<WishListButton
folderId={folderId}
linkId={linkId}
isFavorite={favorite}
/>
)}
<CardContent
elapsedTime={getElapsedTime(created_at)}
description={description}
createdAt={formatData(created_at)}
isHovered={isHovered}
currentLocation={currentLocation}
selectURL={url}
folderList={folderList}
linkId={linkId}
/>
</Card>
</a>
Expand Down
1 change: 1 addition & 0 deletions components/common/CardList/CardListStyled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const CardListContainer = styled.div`
width: 100%;
max-width: 106rem;
row-gap: 2rem;
min-height: 10rem;

@media (min-width: 768px) {
grid-template-columns: repeat(auto-fill, 34rem);
Expand Down
3 changes: 3 additions & 0 deletions components/common/EmptyLink/EmptyLinkStyled.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import styled from "styled-components";

export const EmptyLinkContainer = styled.div`
position: absolute;
left: 50%;
transform: translate(-50%, 0);
width: auto;
height: 10rem;
margin-top: 4rem;
Expand Down
15 changes: 1 addition & 14 deletions components/common/Layout/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
import Footer from "../Footer";
import { PropsWithChildren, useEffect } from "react";
import { PropsWithChildren } from "react";
import { NavigationBar } from "../NavigationBar";
import { useRouter } from "next/router";

export const Layout = ({ children }: PropsWithChildren) => {
const router = useRouter();
const currentPath = router.pathname;

useEffect(() => {
const localStorageToken = localStorage.getItem("accessToken");
if (currentPath !== "/") {
if (localStorageToken === null) {
router.push("/signin");
}
}
}, [currentPath, router]);

return (
<>
<div>
Expand Down
45 changes: 45 additions & 0 deletions components/common/Modals/AddFolder/AddFolder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ModalInput } from "../ModalElements/ModalInput";
import Modal from "../Modal";
import { BaseModalProps } from "../ModalProp";
import { PrimaryButton } from "@styles/common/PrimaryButton";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useInputValue } from "@hooks/useInputValue";
import { MouseEvent } from "react";
import { postNewFolder } from "@data-access/postNewFolder";

export function AddFolder({ handleCloseModal }: BaseModalProps) {
const { insertValue, onChange } = useInputValue();
const queryClient = useQueryClient();
const createFolderMutation = useMutation({
mutationFn: (createFolderName: string) =>
postNewFolder({ folderName: createFolderName }),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["folderList"],
});
},
Comment on lines +16 to +20
Copy link
Collaborator

Choose a reason for hiding this comment

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

Query Key 관리하는건 tkdodo 형님의 이 글이 바이블처럼 여겨지는거 같아서 읽어보시고 적용해보시는걸 추천드립니다!

});

const handleCreateNewFolder = async (
event: MouseEvent<HTMLButtonElement>
) => {
const createFolderName = insertValue;

createFolderMutation.mutate(createFolderName);
handleCloseModal(event);
};

return (
<Modal title={"폴더 추가"} handleCloseModal={handleCloseModal}>
<ModalInput
value={insertValue}
onChange={onChange}
placeholder="내용 입력"
type="text"
></ModalInput>
<PrimaryButton type="button" onClick={handleCreateNewFolder}>
추가하기
</PrimaryButton>
</Modal>
);
}
1 change: 1 addition & 0 deletions components/common/Modals/AddFolder/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./AddFolder";
11 changes: 0 additions & 11 deletions components/common/Modals/AddFolderContent/AddFolderContent.tsx

This file was deleted.

1 change: 0 additions & 1 deletion components/common/Modals/AddFolderContent/index.ts

This file was deleted.

70 changes: 58 additions & 12 deletions components/common/Modals/AddToFolder/AddToFolder.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,67 @@
import { ModalButtonBlue } from "../ModalElements/ModalButtonBlue";
import * as S from "./AddToFolderStyled";
import Modal from "../Modal";
import { AddToFolderProps } from "../ModalProp";
import { PrimaryButton } from "@styles/common/PrimaryButton";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { MouseEvent, useEffect, useState } from "react";
import { postAddToFolder } from "@data-access/postAddToFolder";

export function AddToFolder({
linkURL,
folderList,
handleCloseModal,
handleReset,
}: AddToFolderProps) {
const [selectFolderId, setSelectFolderId] = useState<number>();
const queryClient = useQueryClient();
const addToFolderMutation = useMutation({
mutationFn: ({ url, folderId }: { url: string; folderId: number }) =>
postAddToFolder({ url, folderId }),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: [`folderContents-${selectFolderId}`],
});
queryClient.invalidateQueries({
queryKey: [`folderContents-${""}`],
});
},
});

const handleFolderId = (event: MouseEvent<HTMLButtonElement>) => {
setSelectFolderId(Number(event.currentTarget.id));
};

const handleAddToFolder = async (event: MouseEvent<HTMLButtonElement>) => {
if (linkURL && selectFolderId) {
addToFolderMutation.mutate({ url: linkURL, folderId: selectFolderId });
handleCloseModal(event);
handleReset();
}
codingaring marked this conversation as resolved.
Show resolved Hide resolved
};

export function AddToFolder({ linkURL, data }: AddToFolderProps) {
return (
<>
<Modal handleCloseModal={handleCloseModal} title={"폴더에 추가"}>
<S.SelectLink>{linkURL}</S.SelectLink>
<S.FolderListContainer>
{data?.map((folder) => (
<S.SelectFolder key={folder.id}>
<S.FolderName>{folder.name}</S.FolderName>
<S.FolderCount>{folder.link.count}개 링크</S.FolderCount>
<S.SelectFolderIcon />
</S.SelectFolder>
))}
{folderList?.map((folder) => {
console.log(selectFolderId === folder.id);
return (
<S.SelectFolder
id={folder.id}
key={folder.id}
onClick={handleFolderId}
isSelect={selectFolderId === Number(folder.id)}
>
<S.FolderName>{folder.name}</S.FolderName>
<S.FolderCount>{folder.link_count}개 링크</S.FolderCount>
<S.SelectFolderIcon />
</S.SelectFolder>
);
})}
</S.FolderListContainer>
<ModalButtonBlue type="button">삭제하기</ModalButtonBlue>
</>
<PrimaryButton type="button" onClick={handleAddToFolder}>
추가하기
</PrimaryButton>
</Modal>
);
}
18 changes: 13 additions & 5 deletions components/common/Modals/AddToFolder/AddToFolderStyled.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import styled from "styled-components";

export const AddToFolderContainer = styled.div`
width: 30rem;
display: flex;
flex-direction: column;
`;
export const FolderListContainer = styled.div`
display: flex;
flex-direction: column;
Expand All @@ -8,24 +13,27 @@ export const FolderListContainer = styled.div`
overflow: hidden scroll;
`;

export const SelectFolder = styled.div`
export const SelectFolder = styled.button<{ isSelect: boolean }>`
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
padding: 0.8rem;
gap: 0.8rem;

&:hover {
background-color: var(--light-blue);
}
background-color: ${({ isSelect }) =>
isSelect ? "var(--light-blue)" : "transparent"};
`;

export const SelectLink = styled.p`
width: 30rem;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
color: var(--gray60);
font-size: 1.4rem;
line-height: 2.2rem;
text-align: center;
margin: 0.5rem 0 2.5rem 0;
`;

export const FolderName = styled.p`
Expand Down
32 changes: 28 additions & 4 deletions components/common/Modals/DeleteFolder/DeleteFolder.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
import * as S from "./DeleteFolderStyled";
import { ModalButtonRed } from "../ModalElements/ModalButtonRed";
import { DeleteFolderProps } from "../ModalProp";
import Modal from "../Modal";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { MouseEvent } from "react";
import { deleteFolder } from "@data-access/deleteFolder";

export default function DeleteFolder({
selectFolder,
folderId,
handleCloseModal,
}: DeleteFolderProps) {
const queryClient = useQueryClient();
const deleteFolderMutation = useMutation({
mutationFn: ({ folderId }: { folderId: number | string }) =>
deleteFolder({ folderId }),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["folderList"],
});
},
});

const handleDeleteFolder = (event: MouseEvent<HTMLButtonElement>) => {
deleteFolderMutation.mutate({ folderId: folderId });
handleCloseModal(event);
};

export default function DeleteFolder({ selectFolder }: DeleteFolderProps) {
return (
<>
<Modal title="폴더 삭제" handleCloseModal={handleCloseModal}>
<S.DeleteFolderSubtitle>{selectFolder}</S.DeleteFolderSubtitle>
<ModalButtonRed>삭제하기</ModalButtonRed>
</>
<ModalButtonRed onClick={handleDeleteFolder}>삭제하기</ModalButtonRed>
</Modal>
);
}
Loading