Skip to content

Commit

Permalink
Merge pull request #489 from rladmswo1715/part4-김은재-week19
Browse files Browse the repository at this point in the history
[김은재] Week19
  • Loading branch information
lisarnjs authored Jun 30, 2024
2 parents f22912f + 5b803d8 commit 7a29357
Show file tree
Hide file tree
Showing 25 changed files with 464 additions and 97 deletions.
100 changes: 96 additions & 4 deletions api/folder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { BASE_URL } from "@/constants/url";

export const getFolderNavInfo = async (userId: number) => {
try {
const response = await fetch(`${BASE_URL}/api/users/${userId}/folders`);
const response = await fetch(`${BASE_URL}/users/${userId}/folders`);
if (!response.ok) {
throw new Error(`${response.status}`);
}

const result = await response.json();

return result;
} catch (error) {
if (error instanceof Error) alert(`${error.message}에러 발생!`);
Expand All @@ -19,9 +19,9 @@ export const getFolderListInfo = async (
navId: string | string[] | undefined,
userToken: string | undefined
) => {
let query = "/api/links";
let query = "/links";
if (navId) {
query += `?folderId=${navId}`;
query = `/folders/${navId}${query}`;
}

try {
Expand All @@ -44,3 +44,95 @@ export const getFolderListInfo = async (
return false;
}
};

export const addFolder = async (folderName: string, userToken: string) => {
const response = await fetch(`${BASE_URL}/folders`, {
method: "POST",
headers: {
Authorization: `Bearer ${userToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: folderName,
}),
});

if (!response.ok) {
throw new Error("Failed to add Folder!!");
}
};

export const changeFolderName = async (
pageNavId: string | string[],
folderName: string,
userToken: string
) => {
const response = await fetch(`${BASE_URL}/folders/${pageNavId}`, {
method: "PUT",
headers: {
Authorization: `Bearer ${userToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: folderName,
}),
});

if (!response.ok) {
throw new Error("Failed to add Folder!!");
}
};

export const deleteFolder = async (
pageNavId: string | string[],
userToken: string
) => {
const response = await fetch(`${BASE_URL}/folders/${pageNavId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${userToken}`,
},
});

if (!response.ok) {
throw new Error("Failed to add Folder!!");
}
};

export const addLink = async (
linkUrl: string,
folderId: number,
userToken: string
) => {
const response = await fetch(`${BASE_URL}/links`, {
method: "POST",
headers: {
Authorization: `Bearer ${userToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: linkUrl,
folderId: folderId,
}),
});

if (!response.ok) {
if (response.status === 400) {
throw new Error("이미 존재하는 URL입니다.");
}
throw new Error("Failed to add Folder!!");
}
};

export const deleteLink = async (linkId: number, userToken: string) => {
const response = await fetch(`${BASE_URL}/links/${linkId}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${userToken}`,
},
});

if (!response.ok) {
throw new Error("Failed to add Folder!!");
}
};
6 changes: 4 additions & 2 deletions api/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ export const getSharedFolderInfo = async (
folderId: string | string[] | undefined
) => {
try {
const response = await fetch(`${BASE_URL}/api/folders/${folderId}`);
const response = await fetch(`${BASE_URL}/folders/${folderId}`);
if (!response.ok) {
throw new Error(`${response.status}`);
}

const result = await response.json();

return result;
} catch (error) {
if (error instanceof Error) alert(`${error.message}에러 발생!!`);
Expand All @@ -23,13 +24,14 @@ export const getSharedLinkList = async (
) => {
try {
const response = await fetch(
`${BASE_URL}/api/users/${userId}/links?folderId=${folderId}`
`${BASE_URL}/users/${userId}/links?folderId=${folderId}`
);
if (!response.ok) {
throw new Error(`${response.status}`);
}

const result = await response.json();

return result;
} catch (error) {
if (error instanceof Error) alert(`${error.message}에러 발생2!`);
Expand Down
9 changes: 4 additions & 5 deletions api/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ interface SignUserData {

export const getSignInProfile = async (userToken: string) => {
let result = null;

try {
const response = await fetch(`${BASE_URL}/api/users`, {
const response = await fetch(`${BASE_URL}/users`, {
headers: {
Authorization: `Bearer ${userToken}`,
},
Expand All @@ -34,7 +33,7 @@ export const getUserInfo = async (userId: string) => {
let result = null;

try {
const response = await fetch(`${BASE_URL}/api/users/${userId}`);
const response = await fetch(`${BASE_URL}/users/${userId}`);
if (!response.ok) {
throw new Error(`${response.status}`);
}
Expand All @@ -51,7 +50,7 @@ export const postSign = async (apiUrl: string, userData: SignUserData) => {
let result = null;

try {
const response = await fetch(`${BASE_URL}/api/${apiUrl}`, {
const response = await fetch(`${BASE_URL}/${apiUrl}`, {
method: "POST",
headers: POST_HEADER,
body: JSON.stringify(userData),
Expand All @@ -72,7 +71,7 @@ export const postCheckEmail = async (email: string) => {
let result = null;

try {
const response = await fetch(`${BASE_URL}/api/check-email`, {
const response = await fetch(`${BASE_URL}/users/check-email`, {
method: "POST",
headers: POST_HEADER,
body: JSON.stringify({ email: email }),
Expand Down
15 changes: 9 additions & 6 deletions components/common/KebabList.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
import * as S from "./KebabList.styled";
import useModal from "@/hooks/useModal";
import { ModalParam } from "@/types/Modal";
import LinkDeleteContent from "./modal/modalContent/LinkDeleteContent";
import LinkAddContent from "./modal/modalContent/LinkAddContent";

interface IKebabList {
linkId: number;
linkUrl: string;
setKebabOpen: (isOpen: boolean) => void;
}

const KebabList = ({ linkUrl, setKebabOpen }: IKebabList) => {
const KebabList = ({ linkId, linkUrl, setKebabOpen }: IKebabList) => {
const { openModal } = useModal();

const handleOpenModal = (
e: React.MouseEvent,
{ type, props }: ModalParam
{ props, component }: ModalParam
) => {
e.preventDefault();
setKebabOpen(false);
openModal({ type, props });
openModal({ props, component });
};

return (
<S.KebabList>
<S.KebabListItem
onClick={(e) => {
handleOpenModal(e, {
type: "linkDelete",
props: { title: "링크 삭제", subTitle: linkUrl },
component: <LinkDeleteContent linkId={linkId} />,
});
}}
>
Expand All @@ -34,8 +37,8 @@ const KebabList = ({ linkUrl, setKebabOpen }: IKebabList) => {
<S.KebabListItem
onClick={(e) => {
handleOpenModal(e, {
type: "linkAdd",
props: { title: "폴더에 추가", subTitle: "링크 주소" },
props: { title: "폴더에 추가", subTitle: linkUrl },
component: <LinkAddContent linkUrl={linkUrl} />,
});
}}
>
Expand Down
6 changes: 5 additions & 1 deletion components/common/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ const Link = ({ linkInfo, isSetting }: LinkItemParam) => {
</button>
)}
{isKebabOpen && (
<KebabList linkUrl={linkInfo.url} setKebabOpen={setIsKebabOpen} />
<KebabList
linkId={linkInfo.id}
linkUrl={linkInfo.url}
setKebabOpen={setIsKebabOpen}
/>
)}
</S.AgoBox>
<S.ContentParagraph>{linkInfo.description}</S.ContentParagraph>
Expand Down
22 changes: 3 additions & 19 deletions components/common/modal/ModalPortal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,20 @@ import { useContext } from "react";
import { createPortal } from "react-dom";
import { ModalStateContext } from "@/context/Modal";
import ModalLayOut from "./ModalLayout";
import ShareModalContent from "./modalContent/ShareModalContent";
import FolderAddModalContent from "./modalContent/FolderAddModalContent";
import FolderNameChangeContent from "./modalContent/FolderNameChangeContent";
import FolderDeleteContent from "./modalContent/FolderDeleteContent";
import LinkDeleteContent from "./modalContent/LinkDeleteContent";
import LinkAddContent from "./modalContent/LinkAddContent";
import { TModalParam, ModalType } from "@/types/Modal";

const MODAL_COMPONENTS: Record<ModalType, () => JSX.Element> = {
share: ShareModalContent,
folderAdd: FolderAddModalContent,
folderNameChange: FolderNameChangeContent,
folderDelete: FolderDeleteContent,
linkDelete: LinkDeleteContent,
linkAdd: LinkAddContent,
};
import { TModalParam } from "@/types/Modal";

function MoadlPortal() {
const modalParam: TModalParam = useContext(ModalStateContext);
if (!modalParam) {
return null;
}

const { type, props } = modalParam;
const { props, component } = modalParam;

const Modal = MODAL_COMPONENTS[type];
return createPortal(
<>
<ModalLayOut title={props.title} subTitle={props.subTitle}>
<Modal />
{component}
</ModalLayOut>
</>,
document.getElementById("modal") as HTMLElement
Expand Down
45 changes: 43 additions & 2 deletions components/common/modal/modalContent/FolderAddModalContent.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,52 @@
import { useContext, useState } from "react";
import * as S from "./FolderAddModalContent.styled";
import Button from "@/components/common/Button";
import { useMutation } from "@tanstack/react-query";
import { addFolder } from "@/api/folder";
import { UserInfoContext } from "@/context/User";

const FolderAddModalContent = () => {
const [folderName, setFolderName] = useState("");
const userInfo = useContext(UserInfoContext);

const changeInputFolderName = (e: React.ChangeEvent<HTMLInputElement>) => {
setFolderName(e.target.value);
};

const handleFolderAdd = useMutation({
mutationFn: () => {
if (!userInfo || !userInfo.token) {
return Promise.reject(new Error("UserToken Error!"));
}
return addFolder(folderName, userInfo.token);
},
onSuccess: () => {
alert("폴더 추가 성공");
window.location.reload();
},
});

const handleFolderAddBtnClick = () => {
if (folderName.trim() === "") {
alert("폴더 이름 입력");
return;
}
handleFolderAdd.mutate();
};

return (
<S.FolderAddContent>
<input type="text" placeholder="내용 입력" />
<Button btnType="button" type="folderAdd_modal">
<input
type="text"
value={folderName}
placeholder="내용 입력"
onChange={changeInputFolderName}
/>
<Button
btnType="button"
type="folderAdd_modal"
handleButtonClick={handleFolderAddBtnClick}
>
추가하기
</Button>
</S.FolderAddContent>
Expand Down
40 changes: 38 additions & 2 deletions components/common/modal/modalContent/FolderDeleteContent.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,44 @@
import { deleteFolder } from "@/api/folder";
import Button from "@/components/common/Button";
import { UserInfoContext } from "@/context/User";
import useModal from "@/hooks/useModal";
import { useMutation } from "@tanstack/react-query";
import { useRouter } from "next/router";
import { useContext } from "react";

interface IFolderDeleteContentProps {
pageNavId: string | string[];
}

const FolderDeleteContent = ({ pageNavId }: IFolderDeleteContentProps) => {
const userInfo = useContext(UserInfoContext);
const router = useRouter();
const { closeModal } = useModal();

const handleFolderDeleteBtnClick = () => {
handleFolderDelete.mutate();
};

const handleFolderDelete = useMutation({
mutationFn: () => {
if (!userInfo || !userInfo.token) {
return Promise.reject(new Error("UserToken Error!"));
}
return deleteFolder(pageNavId, userInfo.token);
},
onSuccess: () => {
alert("삭제 성공");
closeModal();
router.replace("/folder");
},
});

const FolderDeleteContent = () => {
return (
<Button btnType="button" type="folderDelete_modal">
<Button
btnType="button"
type="folderDelete_modal"
handleButtonClick={handleFolderDeleteBtnClick}
>
삭제하기
</Button>
);
Expand Down
Loading

0 comments on commit 7a29357

Please sign in to comment.